Unsolved Can QChar functions work with QStrings ?
-
Hi everyone,
I'm trying to code a function which can distinguish letters in strings from numerals
and punctuation marks. The problem is that I have used QChar function isLetter and isLetterorNumber(). The compiler gives me no problem but I'm not sure if it will give me any random problems when using it. Could someone tell me if it'll be ok and if not how to make it work ? Also I'm not sure if the last line size = aword.size() is required or if it'll work without it. Thanks.for (int i = 0, size = aword.size(); i < size; i++) { if (aword[i].isLetterOrNumber() && aword[i].isLetter()) { aword.remove(i--, 1); size = aword.size(); } }
-
If
aword
is aQString
then yoir code is Ok from compiler side.But:
if (aword[i].isLetterOrNumber() && aword[i].isLetter())
that looks strange.
What is your goal, actually? QString has dedicated
remove
functions with regular expressions that migth do the work faster and in one line.Regards
-
Also I'm not sure if the last line size = aword.size() is required or if it'll work without it.
The way you have written it, with
size
as a variable, yes, you do need to go eithersize = aword.size();
orsize--
when you remove a character, as the size has changed. SinceQString::size()
is such a "cheap" operation, you could not bother with a variable and save a line via:for (int i = 0; i < aword.size(); i++) if (aword[i].isLetter()) aword.remove(i--, 1);
As @aha_1980 has said, you could use a "regular expression" to remove all unwanted characters in a single statement without a loop, though whether at this stage you would find that more complex than what you have is another matter.
-
@aha_1980 said in Can QChar functions work with QStrings ?:
QString has dedicated remove functions with regular expressions that migth do the work faster and in one line.
True for all latin-alphabet languages, not 100% sure it is safe for the entirety of unicode.
-
Sadly QString has no QString::erase()... :(
#include <QtCore> int main(int argc, char **argv) { QCoreApplication app(argc, argv); if (argc != 2) return 0; QString str = app.arguments().at(1); const auto checkFunc = [](const QChar c) -> bool { return c.isLetterOrNumber(); }; //str.erase(std::remove_if(str.begin(), str.end(), checkFunc), str.end()); str.chop(str.end() - std::remove_if(str.begin(), str.end(), checkFunc)); qDebug() << app.arguments().at(1) << str; return 0; }
-
@VRonin said in Can QChar functions work with QStrings ?:
True for all latin-alphabet languages
Therefore my question, what the OP really wants to do.
not 100% sure it is safe for the entirety of unicode.
https://stackoverflow.com/questions/38001256/handling-accented-letters-in-qregularexpressions-in-qt5
-
What I'm trying to do is to check the QString for characters which aren't letters and then delete them. For example, "H?e__llo" would become "Hello".
-
You are right about isLetterorNumber being redundant I thought it made sense when only isLetter () is what I need. My new code would be:
for (int i = 0, size = aword.size(); i < size; i++) { if (aword[i].isLetter() != 1) { aword.remove(i--, 1); size = aword.size(); } }
-
But I'm still not sure if it'll work. I've read the docs but it says that isLetter() works only for UCS-4 encoded characters but the character of a QString corresponds to one UTF-16 code unit. In that case, I'm not sure if my code would eventually give rise to random behaviour.
-
@jefazo92 said in Can QChar functions work with QStrings ?:
works only for UCS-4 encoded characters
You read the wrong documentation - you're using QChar::isLetter(), not the static QChar::isLetter(uint).
-
I've read the docs but it says that isLetter() works only for UCS-4 encoded characters
And that is only correct for this overload, which you are not using. You are using this.
But: You still didn't tell us what you really want to do. I read your last code, as if you want to remove all non-letter chars from the string.
Example:
"%$Hello/World!["
>"HelloWorld"
Is that correct? -
So what should I do in that case ? I'm a bit lost here.
-
Yes exactly. That's what I want.
-
@jefazo92 Then here's a one-liner:
#include <QDebug> #include <QRegularExpression> int main(int argc, char *argv[]) { QString s = "%$Hello/World!["; s.remove(QRegularExpression("[^\\p{L}]")); qDebug() << "s =" << s; }
Output:
s = "HelloWorld"
-
@aha_1980 said in Can QChar functions work with QStrings ?:
QRegularExpression
Would that then remove any punctuation marks, numbers and blank spaces ? Or would I have to add something else ?
-
Also does that mean that my line above would then not work as it should ?
-
Your code should work as well, I'd just clean it up a bit:
for (int i = 0; i < aword.size(); i++) { if (!aword[i].isLetter()) aword.remove(i--, 1); }
However, why re-invent the wheel if there is a ready-made function?
-
@aha_1980 said in Can QChar functions work with QStrings ?:
QRegularExpression
Hi @aha_1980,
Thank you a lot for your reply. If it's not too much asking how did you find QRegularExpression ? Like I'm ctrl+F at the QStrings doc but I get 53 coincidences I don't know which of them all is the one that suits me for this example. I'm trying to understand what the [^\p{L}] in the QRegularExpression("[^\p{L}]") means. Also how did you know that the QChar functions I used for QString would work ? Since I'm still a rooky, all these details are important to help me fend off by myself in the future. Thanks.
-
You can find the documentation here: QRegularExpression
-
@Christian-Ehrlicher
To be fair to @jefazo92, that docs page does not begin to attempt to explain[^\p{L}]
, or even the\p{L}
. In fact it only refers the reader to other sources, such as http://pcre.org/pcre.txt, for all syntax.I like reg exes, and have used them for years (decades), but it's only right to say to the OP that they are a bit tricky and he'll have to go outside Qt docs to find out about them. A resource I would recommend is an on-line constructor/tester like https://regex101.com/ or https://regexr.com/, though they are not very tutorially.