I have an issue where I have a RegEx, [^/\&\?]+.\w{3,4}(?=([\?&].*$|$)), but I cannot get it to work with the function at [ 1 ] below.
[ 1 ] - http://doc.qt.io/qt-5/qregexp.html
This is the code I've tried:
QRegExp rx("[^/\\\\&\\?]+\\.\\w{3,4}(?=([\\?&].*$|$))", Qt::CaseInsensitive, QRegExp::RegExp);
std::ostringstream list;
int pos = 0;
while ((pos = rx.indexIn(url, pos)) != -1) {
list << rx.cap(1).toStdString();
pos += rx.matchedLength();
}
return list;
It's supposed to extract the filename off a URL, but just returns nothing instead. I'm not sure what's going wrong. Can someone please offer assistance? Thank you in advance.
Qt has QUrl class for parsing URL etc. And there is QUrl::fileName method:
QUrl url("http://qt-project.org/support/file.html");
// url.adjusted(RemoveFilename) == "http://qt-project.org/support/"
// url.fileName() == "file.html"
Related
My problem is that i have several folders with the names "MORE0001" "MORE0002" etc and they contain one .SPE-file each.
I want to know if there is a way to extract all the .SPE-files to ONE folder by iterating through all the single-MORE...-folders.
I need sth. like this:
for (int i=0; i<10;i++){
newfile = getfile("directory/MORE%04d/filename.SPE", i);
// copy newfile to a new directory..
}
I hope you guys can help me find an easy solution, because i didn´t find a similar problem yet.
it´s just TOO easy..
i can just use the rename-function..
so it would be like:
rename(path/filename.SPE, newpath/filename.SPE);
thanks, but solved it myself ;)!
I have created one sample program, which might helps to resolve your problem.
#include<Windows.h>
#include<regex>
using namespace std;
void main()
{
regex e1("MORE\\d+");
string szDir = "C:\\*";
WIN32_FIND_DATA ffd;
HANDLE hFind = FindFirstFileA(szDir.c_str(), &ffd);
do
{
if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
if (regex_match(ffd.cFileName,e1 ))
{
string s1 = ffd.cFileName;
string s2 = "C:\\" + s1 + "\\*";
WIN32_FIND_DATA ffdMORE;
HANDLE hFindMORE = FindFirstFile(s2.c_str(), &ffdMORE);
do
{
regex e2("\\w+.SPE");
if (regex_match(ffdMORE.cFileName,e2))
{
string commondir = "C:\\CommonDir\\";
string sourcePath = "C:\\" + s1 + "\\";
CopyFile(sourcePath.append(ffdMORE.cFileName).c_str(), commondir.append(ffdMORE.cFileName).c_str(), FALSE);
}
} while (FindNextFile(hFindMORE, & ffdMORE) != 0);
}
}
} while (FindNextFile(hFind, &ffd) != 0);
}
Thanks,
Bharathraj
I am using the following code to replace a string within a string.
The same code as below is working in Visual Studio 2012 but not in Eclipse, and I can't figure out why.
The error is about invalid arguments in the find and replace functions of std::string:
void ReplaceStringInPlace(std::string& subject, const std::string& search, const std::string& replace)
{
// handle error situations/trivial cases
if (search.length() == 0)
{
// searching for a match to the empty string will result in an infinite loop
return;
}
if (subject.length() == 0)
{
return; // nothing to match against
}
std::size_t pos = 0;
while ((pos = subject.find(search, pos)) != std::string::npos)
{
subject.replace(pos, search.length(), replace);
pos += replace.length();
}
}
The error message is as follows:
Invalid arguments '
Candidates are:
? find(const char *, ?, ?)
? find(const stlpmtx_std::basic_string<char,stlpmtx_std::char_traits<char>,stlpmtx_std::allocator<char>> &, ?)
? find(const char *, ?)
? find(char, ?)
'
Problem 1:-
Is there a different way to use these functions in Eclipse? What should I do to make the error go away?
Problem 2 :-
What does the ? sign mean in the error messages?
How I should parse QString, which contains system variables ?What I want:
QString path = "%WINDIR%\\System32\\";
QString output = parse(path);
QDebug()<<output; \\ output is "C:\\Windows\\System32\\"
I think you want something like this:
// Untested
QString parse(QString str)
{
int pos = 0;
QRegExp rx("%([^%]+)%"); // Match env var between two '%'
rx.setMinimal(true);
while((pos = rx.indexIn(str, pos)) != -1)
{
// Replace env var
QString capture = rx.cap(1);
QString replacement = getenv(capture.toAscii());
str.replace("%" + capture + "%", replacement);
// Skip env var + two '%'
pos += rx.matchedLength() + 2;
}
return str;
}
QString path = parse("%WINDIR%\\System32");
I think, this is what you looking for. Please try this
QString windir = getenv ("WINDIR"); // Expanded
if (windir.isEmpty()) {
fprintf(stderr, "Generator requires WINDIRto be set\n");
}
windir += "\\System32";
qDebug()<<windir;
im writing a simple webcrawler. the problem is, with the link extraction.
i uses the cpp-netlib with boost. here a few lines of my CLink Class.
CLink::CLink(const CLink& father, const std::string& relUrl )
{
uri = relUrl;
boost::network::uri::uri instance(relUrl);
boost::network::uri::uri instanceFather(father.uri);
if ( (valid = boost::network::uri::is_valid(instance)) == 1)
{
scheme = boost::network::uri::scheme(instance);
user_info = boost::network::uri::user_info(instance);
host = boost::network::uri::host(instance);
port = boost::network::uri::port(instance);
path = boost::network::uri::path(instance);
query = boost::network::uri::query(instance);
fragment = boost::network::uri::fragment(instance);
uri = scheme;
uri += "://";
uri += host;
uri += path;
}
else
{
if ( (valid = boost::network::uri::is_valid(instanceFather)) == 1)
{
scheme = boost::network::uri::scheme(instanceFather);
user_info = boost::network::uri::user_info(instanceFather);
host = boost::network::uri::host(instanceFather);
port = boost::network::uri::port(instanceFather);
path = boost::network::uri::path(instance);
query = boost::network::uri::query(instance);
fragment = boost::network::uri::fragment(instance);
uri = scheme;
uri += "://";
uri += host;
uri += path;
}
}
};
CLink::CLink( const std::string& _url )
{
uri = _url;
boost::network::uri::uri instance(_url);
if ( (valid = boost::network::uri::is_valid(instance) ) == 1)
{
scheme = boost::network::uri::scheme(instance);
user_info = boost::network::uri::user_info(instance);
host = boost::network::uri::host(instance);
port = boost::network::uri::port(instance);
path = boost::network::uri::path(instance);
query = boost::network::uri::query(instance);
fragment = boost::network::uri::fragment(instance);
uri = scheme;
uri += "://";
uri += host;
uri += path;
}
else
std::cout << "err " << std::endl;
};
the links from the webpage i took with the htmlcxx lib. i took the HTML::Node and normalize them wih the boost filesystem.
if ( url.find("http://") == std::string::npos)
{
std::string path = link.get_path() + url;
url = link.get_host() + path;
boost::filesystem::path result;
boost::filesystem::path p(url);
for(boost::filesystem::path::iterator it=p.begin(); it!=p.end(); ++it)
{
if(*it == "..")
{
if(boost::filesystem::is_symlink(result) )
result /= *it;
else if(result.filename() == "..")
result /= *it;
else
result = result.parent_path();
}
else if(*it == ".")
{
// Ignore
}
else
{
// Just cat other path entries
result /= *it;
}
}
url = "http://" + result.string();
}
return ret;
Now the problem is.
i try to fetch http://www.wikipedia.de/ and i get the urls like
properties
http://wikimedia.de/wiki/Vereinszeitung
... ...
and on the site http://wikimedia.de/wiki/Vereinszeitung there is a link like /wiki/vereinsatzung
so often i get links like
http://wikimedia.de/wiki/Vereinszeitung/wiki/Freies_Wissen
does someone have a idee?
You need to have a special case for absolute links (those that start with /).
If the href starts with /, then the resulting link should be (using the terms from The URI template which come from the RFC):
[scheme]://[authority][what you got in href]
What you are currently constructing is:
[scheme]://[authority][path][what you got in href]
So you're duplicating the path information.
So if link.get_path() starts with /, you should simply change:
std::string path = link.get_path() + url;
url = link.get_host() + path; // this is incorrect btw, missing the [port]
to
url = link.get_host() + ":" + link.get_port() + url;
It would probably be cleaner to do the path normalization on the path only, not on the URL (i.e. add host:port after normalizing the path).
[And I think your code will fail if it encounters an https link.]
If i have a string as such
"I am not here... \n..Hello\n.\n....Whats happening"
I want to replace the above string so:
"I am not here... \n..Hello\n. \n....Whats happening"
^ Space added
Just a bit of a background on what im doing. Im using sendmail in C++ and \n.\n is End Of Message Equivalent of sendmail. I just created a class that uses sendmail to send mails. but obviously if the user from the outsite gives sendmail that command i want it to be removed. Here is my message function just incase.:
//Operator to add to the message
void operator<<(string imessage){
if (imessage != ""){ message += imessage; }
}
How would i go about doing this. Thanks in advance :D
This is my last version :)
This code handles the case mentioned by #Greg Hewgill
string& format_text(string& str)
{
const string::size_type dot_offset = 2;
string::size_type found_at_start = str.find("\n.\n"),
found_at = str.find("\n.\n");
if(found_at_start != string::npos)
str.insert(0, " ");
while(found_at != string::npos)
{
str.insert(found_at+dot_offset+1, " ");
found_at = str.find("\n.\n", found_at+1);
}
return str;
}
int main()
{
string text = ".\nn\n.\nn";
std::cout << format_text(text);
}
Look up String.find and String.replace
For example (not tested)
string endOfMessage = "\n.\n";
string replacement = "\n. \n";
size_t position;
while (position = message.find(endOfMessage))
{
message.replace(position, endOfMessage.length(), replacement);
}
This is derived from Dan McG's answer so upvote him ;)
string endOfMessage = "\n.\n";
string replacement = "\n. \n";
size_t position;
while (position = message.find(endOfMessage, position) != message.npos)
{
message.replace(position, endOfMessage.length(), replacement);
position += replacement.length();
}
Boost has Boost.Regex (a regular expression module). Might be overkill if this is the only replacement you need to do.
Use std::search and the insert method of sequence containers such as string, deque, or whatever you use to store the message text.
typedef std::string::iterator SIter; // or whatever container you use
static const char *end_seq = "\n.\n";
for ( SIter tricky_begin = msg.begin();
tricky_begin = std::search( tricky_begin, msg.end(), end_seq, end_seq+3 ),
tricky_begin != msg.end(); ) {
tricky_begin = msg.insert( tricky_begin + 2, ' ' );
}