I am trying to parse a QString of this form:
QString str = "34 t:513 l:21 o:0x0147 [FBI] Miscellaneous No. : 89f2aad996ae4a5c961a 123 532af2";
QRegExp tagExp(":");
QStringList firstList = str.split(tagExp);
However I need only "9f2aad996ae4a5c961a 123 532af2". So is it possible to get the substring following ": "?
If I understand you correctly you want the last element of the list (after the last ":"). You can do the following:
QRegExp tagExp(":");
QStringList firstList = str.split(tagExp);
// Get the last string from list:
// "34 t"
// "513 l"
// "21 o"
// "0x0147 [FBI] Miscellaneous No. "
// "89f2aad996ae4a5c961a 123 532af2" <<-- this is the last element in list
QString requiredPart = firstList.takeLast();
The function takeLast gets the last string and returns it and also removes it from the list. If you don't want to remove the last element from the list you can do something like:
QString requiredPart = firstList.value(firstList.length() - 1);
or
QString requiredPart = firstList.at(firstList.length() - 1);
or
QString requiredPart = firstList[firstList.length() - 1];
But the first option is the safest as it covers you for "out of bounds" issues better.
You can also use:
requiredPart = requiredPart.trimmed();
to remove any spaces at the start / end. Or go further and use:
requiredPart = requiredPart.simplified();
To remove excess white-space within the string. You probably don't need this.
Related
How to remove /Job from /home/admin/job0/Job
QString name = "/home/admin/job0/Job"
I want to remove last string after"/"
You have QString::chop() for the case when you already know how many characters to remove.
It is same as QString::remove(), just works from the back of string.
Find last slash with QString::lastIndexOf.
After that get substring with QString::left till the position of the last slash occurrence
QString name = "/home/admin/job0/Job";
int pos = name.lastIndexOf(QChar('/'));
qDebug() << name.left(pos);
This will print:
"/home/admin/job0"
You should check int pos for -1 to be sure the slash was found at all.
To include last slash in output add +1 to the founded position
qDebug() << name.left(pos+1);
Will output:
"/home/admin/job0/"
Maybe easiest to understand for later readers would probably be:
QString s("/home/admin/job0/Job");
s.truncate(s.lastIndexOf(QChar('/'));
qDebug() << s;
as the code literaly says what you intended.
You can do something like this:
QString s("/home/admin/job0/Job");
s.remove(QRegularExpression("\\/(?:.(?!\\/))+$"));
// s is "/home/admin/job0" now
If you are using Qt upper than 6 and sure that "/" constains in your word you should use QString::first(qsizetype n) const function instead QString::left(qsizetype n) const
Example:
QString url= "/home/admin/job0/Job"
QString result=url.first(lastIndexOf(QChar('/')));
If you run these code:
QElapsedTimer timer;
timer.start();
for (int j=0; j<10000000; j++)
{
QString name = "/home/admin/job0/Job";
int pos = name.lastIndexOf("/");
name.left(pos);
}
qDebug() << "left method" << timer.elapsed() << "milliseconds";
timer.start();
for (int j=0; j<10000000; j++)
{
QString name = "/home/admin/job0/Job";
int pos = name.lastIndexOf(QChar('/'));
name.first(pos);
}
qDebug() << "frist method" << timer.elapsed() << "milliseconds";
Results:
left method 10034 milliseconds
frist method 8098 milliseconds
sorry for replying to this post after 4 years, but I have (I think) the most efficient answer.
You can use
qstr.remove(0, 1); //removes the first character
qstr.remove(1, 1); //removes the last character
Thats everything you have to do, to delete characters ONE BY ONE (first or last) from a QString, until 1 character remains.
I have a long QString named text, and I am looking to extract all the words in it, which have their first letter in uppercase. Is there any way to use the QString::split() method to test each word separately ? Or even a way to do it without having to split text ?
What about:
QString text = "Text is long. Or maybe longer. Yay!";
QRegularExpression regexp("[A-Z][^A-Z]*");
QRegularExpressionMatchIterator match = regexp.globalMatch(text);
QVector<QString> vec;
while(match.hasNext())
vec.append(match.next().capturedTexts());
The regular expression matches everything from an upper case letter forward until next capital letter. Then since you wanted all the matches you iterate through them and save them to QVector<QString> (or QStringList if you so wish though it is discouraged to use).
Without splitting:
QRegExp rx("\\b[A-Z]\\w+\\b"); // Or "\\b[A-Z]\\w*\\b" if you want to include one-character words
int pos = 0;
while ((pos = rx.indexIn(text, pos)) != -1)
{
QString your_word = rx.cap(); // every word is here
pos += rx.matchedLength();
}
I have custom(dynamic QString) for example something like this 123+555 and i need to get this after +.Also there can be something different then + (/,*,- etc.). My question is how to get part of string after some char.
Use the split function, which allows you to specify the separator and returns a list of the elements.
QString string("123+555");
QStringList listItems = string.split('+', QString::SkipEmptyParts);
QString finalString = listItems[1];
Alternatively, you can find by index the separating character location and use that with a call to right
Since you're usin Qt, you could try the class: QRegExp.
With such class you could write code like this:
// This code was not tested.
QRegExp rx("(\\d+)(\\+|\\-|\\*|/)(\\d+)"); // Be aware, I recommend you to read the link above in order to see how construct the proper regular expression.
int pos = rx.indexIn("23+344");
if (pos > -1) {
QString number_1 = rx.cap(1); // "23"
QString op = rx.cap(2); // "+"
QString number_2 = rx.cap(3); // "344"
// ...
}
This way you don't have to write code to check which of the characters(operators) "+, -, *, /" is present to then perform a split on the string depending on what character was found.
How can i find a specific character in a QFile which has a text in it?
for example i have ' $5000 ' written somewhere in my file. in want to find the "$" sign so i will realize that I've reached the number.
I tried using QString QTextStream::read(qint64 maxlen) by putting 1 as the maxlen :
QFile myfile("myfile.txt");
myfile.open(QIODevice::ReadWrite | QIODevice::Text);
QTextStream myfile_stream(&myfile);
while(! myfile_stream.atEnd())
{
if( myfile_stream.read(1) == '$')
{
qDebug()<<"found";
break;
}
}
and i get "error: invalid conversion from 'char' to 'const char* "
i also tried using the operator[] but apparently it can't be used for files.
Read in a line at a time and search the text that you've read in
QTextStream stream(&myFile);
QString line;
do
{
line = stream.readLine();
if(line.contains("$"))
{
qDebug()<<"found";
break;
}
} while (!line.isNull());
The error message you've posted doesn't match the issue in your code. Possibly the error was caused by something else.
QTextStream::read returns QString. You can't compare QString and const char* directly, but operator[] can help:
QString s = stream.read(1);
if (s.count() == 1) {
if (s[0] == '$') {
//...
}
}
However reading a file by too small pieces will be very slow. If your file is small enough, you can read it all at once:
QString s = stream.readAll();
int index = s.indexOf('$');
If your file is large, it's better to read file by small chunks (1024 bytes for example) and calculate the index of found character using indexOf result and count of already read chunks.
a single char could be read with
QTextStream myfile_stream(&myfile);
QChar c;
while (!myfile_stream.atEnd())
myfile_stream >> c;
if (c == '$') {
...
}
myfile_stream.read(1) - this is not good practice, you should not read from file one byte at a time. Either read the entire file, or buffered/line by line if there is a risk for the file to be too big to fit in memory.
The error you get is because you compare a QString for equality with a character literal - needless to say that is not going to work as expected. A string is a string even if there is only one character in it. As advised - use either the [] operator or better off for reading - QString::at() const which is guaranteed to create no extra copy. You don't use it on the QFile, nor on the QTextStream, but on the QString that is returned from the read() method of the text stream targeted at the file.
Once you have the text in memory, you can either use the regular QString methods like indexOf() to search for the index of a contained character.
in want to find the "$" sign so i will realize that I've reached the
number.
It sounds to me that you're searching for the '$' symbol because you're more interested in the dollar value that follows it. In this case, I suggest reading the files line by line and running them through a QRegExp to extract any values you're looking for.
QRegExp dollarFind("\\$(\\d+)");
while(!myfile_stream.atEnd()){
QString line = myfile_stream.readLine();
if (dollarFind.exactMatch(line)){
QStringList dollars = dollarFind.capturedTexts();
qDebug() << "Dollar values found: " << dollars.join(", ");
}
}
I want to get QString from another QString, when I know necessary indexes.
For example:
Main string: "This is a string".
I want to create new QString from first 5 symbols and get "This ".
input : first and last char number.
output : new QString.
How to create it ?
P.S. Not only first several letters, also from the middle of the line, for example from 5 till 8.
If you do not need to modify the substring, then you can use QStringRef. The QStringRef class is a read only wrapper around an existing QString that references a substring within the existing string. This gives much better performance than creating a new QString object to contain the sub-string. E.g.
QString myString("This is a string");
QStringRef subString(&myString, 5, 2); // subString contains "is"
If you do need to modify the substring, then left(), mid() and right() will do what you need...
QString myString("This is a string");
QString subString = myString.mid(5,2); // subString contains "is"
subString.append("n't"); // subString contains "isn't"
Use the left function:
QString yourString = "This is a string";
QString leftSide = yourString.left(5);
qDebug() << leftSide; // output "This "
Also have a look at mid() if you want more control.