How to split QString based on a given character length? - c++

I am trying to split QString based on 19 characters per group.
Here is the string:
+1.838212011719E+04-1.779050827026E+00 3.725290298462E-09 0.000000000000E+00
I wish to split it into:
+1.838212011719E+04
-1.779050827026E+00
3.725290298462E-09
0.000000000000E+00
I have tryed using QRegularExpression, but I could not come up with a solution.
How to do this?

Solution
I would suggest you to use a loop instead of a regular expression.
Example
Here is an example I have prepared for you of how to implement this in C++:
bool splitString(const QString &str, int n, QStringList &list)
{
if (n < 1)
return false;
QString tmp(str);
list.clear();
while (!tmp.isEmpty()) {
list.append(tmp.left(n));
tmp.remove(0, n);
}
return true;
}
Note: Optionally you can use QString::trimmed(), i.e. list.append(tmp.left(n).trimmed());, in order to get rid of the leading whitespace.
Result
Testing the example with your input:
QStringList list;
if (splitString("+1.838212011719E+04-1.779050827026E+00 3.725290298462E-09 0.000000000000E+00", 19, list))
qDebug() << list;
produces the following results:
without QString::trimmed()
("+1.838212011719E+04", "-1.779050827026E+00", " 3.725290298462E-09", " 0.000000000000E+00")
with QString::trimmed()
("+1.838212011719E+04", "-1.779050827026E+00", "3.725290298462E-09", "0.000000000000E+00")

Use this regular expression:
^(.{19})(.{19})(.{19})(.{19})
I would also recommend using a tool like RegEx101. Give it a try ans see what happens.

Related

Boost::xpressive regex_search concatenate matches in a single string

I want to concatenate all matches found by regex_search into a single string, and then return it. I tried doing it with std::accumulate, but failed.
Is there a way to return something like std::accumulate(what.begin()+1, what.end(), someFunc)?
I'm not very familiar with functional programming. I know that I can make a for loop that adds strings together, but I want to try doing it otherwise. Thanks in advance!
Here is a pseudo-code snippet that might help you better understand what I want to do.
std::string foo(const std::string& text)
{
using namespace boost::xpressive;
sregex srx = +_d >> as_xpr("_") >> +_d; // some random regex
smatch what;
if (regex_search(filename, what, srx))
{
// Here I want to return a string,
// concatenated from what[1].str() + what[2].str() + ... + what[n].str();
// How do I do this?
// What about what[1].str() + "-" + what[2].str()...?
}
return std::string();
}

Extract the string between two words using RegEx in QT [duplicate]

can anybody help me with this?
I have a string which contains N substrings, delimited by tags and I have to get ALL of the substrings. The string is like
STARTfoo barENDSTARThi there!ENDSTARTstackoverflowrulezEND
I would like to get all the strings between START/END tags, I tried with a couple of regular expressions with no luck:
(START)(.*)(END) gives me ALL the contend between the first and last tag
(START)(\w+)(END) gives me no result
The code is much simple:
QString l_str "STARTfoo barENDSTARThi there!ENDSTARTstackoverflowrulezEND";
QRegExp rx("(START)(\w+)(END)");
QStringList list;
int pos = 0;
while ((pos = rx.indexIn(l_str, pos)) != -1)
{
list << rx.cap(1);
pos += rx.matchedLength();
}
qWarning() << list;
I'd like a resulting list like:
STARTfoo barEND
STARThi there!END
STARTstackoverflowrulezEND
Any help?
Thanks!
Use rx.setMinimal(true) with .* to make it lazy:
QRegExp rx("START.*END");
rx.setMinimal(true);
See the QRegExp::setMinimal docs:
Enables or disables minimal matching. If minimal is false, matching is greedy (maximal) which is the default.

In Qt; what is the best method to capitalise the first letter of every word in a QString?

I am thinking of regular expressions, but that is not exactly readable. There are also functions like s.toUpper() to consider, and probably other things as well.
So what is the best method for capitalising the first letter of words in a QString?
Using this example as a reference, you can do something like this:
QString toCamelCase(const QString& s)
{
QStringList parts = s.split(' ', QString::SkipEmptyParts);
for (int i = 0; i < parts.size(); ++i)
parts[i].replace(0, 1, parts[i][0].toUpper());
return parts.join(" ");
}
Exactly the same, but written differently :
QString toCamelCase(const QString& s)
{
QStringList cased;
foreach (QString word, s.split(" ", QString::SkipEmptyParts))cased << word.at(0).toUpper() + word.mid(1);
return cased.join(" ");
}
This uses more memory but is without pointer access (no brackets operator).
There is an alternative way of doing this which iterates using references to the words and modifies the first character using a QChar reference instead:
QString capitalise_each_word(const QString& sentence)
{
QStringList words = sentence.split(" ", Qt::SkipEmptyParts);
for (QString& word : words)
word.front() = word.front().toUpper();
return words.join(" ");
}
Note that Qt::SkipEmptyParts is required here (as in the other answers to this question) since the first character of each word is assumed to exist when capitalising. This assumption will not hold with Qt::KeepEmptyParts (the default).
Incredible C++/Qt... You just want to get some chars ored with 0x20...

Non matching number Regex in Qt

I am working on a number parser for q Qt calculator. I have create a few regex in order to match with the different kinds of number:
Rationnal : ^[+-]?\d+\/[+-]?\d+$
Integer : ^[+-]?\d+\.?0*$
Real : ^[+-]?\d*\.0*[1-9][0-9]*$
Complexe : ^[+-]?[0-9]*(\.[0-9]*|\/[+-]?[0-9]+)?\$[+-]?[0-9]*(\.[0-9]*|\/[+-]?[0-9]+)?$
I try to use them with the following fuction on QString:
parser.h :
bool isRationnal(const QString s)
{
QRegExp ratioExp ("^[+-]?\d+\/[+-]?\d+$");
return ratioExp.exactMatch(s);
}
bool isInteger(const QString s)
{
QRegExp regExp ("^[+-]?\d+\.?0*$");
return regExp.exactMatch(s);
}
bool isReal(const QString s)
{
QRegExp regExp ("^[+-]?\d*\.0*[1-9][0-9]*$");
return regExp.exactMatch(s);
}
bool isComplex(const QString s)
{
QRegExp regExp ("^[+-]?[0-9]*(\.[0-9]*|\/[+-]?[0-9]+)?\$[+-]?[0-9]*(\.[0-9]*|\/[+-]?[0-9]+)?$");
return regExp.exactMatch(s);
}
bool isNumber(const QString s){
bool ok=false;
s.toInt(&ok);
return ok;
}
main.c :
QString test ="6/90";
if(isReal(test))
printf("real\n");
if(isInteger(test))
printf("Integer\n");
if(isRationnal(test))
printf("Rationnal\n");
if(isNumber(test))
printf("Number\n");
else printf("et merde\n");
QRegExp ratioExp ("^[+-]?\d+\/[+-]?\d+$");
QRegExp IntExp ("^[+-]?\d+\.?0*$");
QRegExp RealExp ("^[+-]?\d*\.0*[1-9][0-9]*$");
QRegExp CplxExp ("^[+-]?[0-9]*(\.[0-9]*|\/[+-]?[0-9]+)?\$[+-]?[0-9]*(\.[0-9]*|\/[+-]?[0-9]+)?$");
if(ratioExp.isValid())
printf("ratio valide\n");
if(IntExp.isValid())
printf("int valide\n");
if(RealExp.isValid())
printf("real valide\n");
if(CplxExp.isValid())
printf("cplx valide\n");
return 0;
}
I tried to run this code with several QString which are numbers, but it usually fail. Especially : it doesn't mathc with number if there is only one caracter like test="4".
Do you know why are those boolean function failing? Maybe I am using the wrong Qt function but after trying several this one looks like what I am searching for.
Feel free to give constructive critism,
Thank you very much,
Théophile
Your expression is fine, but replace \d with \\d. Tested you code in my program.
And I really recommend to this site which can debug your expression online.
Details from Qt Official Documentation :
Note: The C++ compiler transforms backslashes in strings. To include a
\ in a regexp, enter it twice, i.e. \. To match the backslash
character itself, enter it four times, i.e. \\.

Find strings between two tags with regex in Qt

can anybody help me with this?
I have a string which contains N substrings, delimited by tags and I have to get ALL of the substrings. The string is like
STARTfoo barENDSTARThi there!ENDSTARTstackoverflowrulezEND
I would like to get all the strings between START/END tags, I tried with a couple of regular expressions with no luck:
(START)(.*)(END) gives me ALL the contend between the first and last tag
(START)(\w+)(END) gives me no result
The code is much simple:
QString l_str "STARTfoo barENDSTARThi there!ENDSTARTstackoverflowrulezEND";
QRegExp rx("(START)(\w+)(END)");
QStringList list;
int pos = 0;
while ((pos = rx.indexIn(l_str, pos)) != -1)
{
list << rx.cap(1);
pos += rx.matchedLength();
}
qWarning() << list;
I'd like a resulting list like:
STARTfoo barEND
STARThi there!END
STARTstackoverflowrulezEND
Any help?
Thanks!
Use rx.setMinimal(true) with .* to make it lazy:
QRegExp rx("START.*END");
rx.setMinimal(true);
See the QRegExp::setMinimal docs:
Enables or disables minimal matching. If minimal is false, matching is greedy (maximal) which is the default.