I'm trying to change user input in wildcard form ("*word*")
to a regular expression format. To that end, I'm using the code below to strip off the '*'
at the beginning and end of the input so that I can add the regular expression characters on either end:
string::iterator iter_begin = expressionBuilder.begin();
string::iterator iter_end = expressionBuilder.end();
iter_end--;
if ((char)*iter_begin == '*' && (char)*iter_end == '*')
{
expressionBuilder.erase(iter_begin);
expressionBuilder.erase(iter_end);
expressionBuilder = "\\b\\w*" + expressionBuilder + "\\w*\\b";
}
However, the call to "expressionBuilder.erase(iter_end)"
does not erase the trailing '*'
from the input string so I wind up with an incorrect regular expression. What am I doing wrong here? "(char)*iter_end == '*'"
must be true for the code inside the if statment to run (which it does), so why doesn't the same iterator work when passed to erase()?
Your original code and the proposed solutions so far have a couple of problems in addition to the obvious problem you posted about:
Now, the last two items might not really be a problem if the code that uses the snippet/routine is already validating that the string has at least 2 characters, but in case that's not the situation, I believe the following to be more robust in the face of arbitrary values for expressionBuilder:
// using the reverse iterator rbegin() is a nice easy way
// to get the last character of a string
if ( (expressionBuilder.size() >= 2) &&
(*expressionBuilder.begin() == '*') &&
(*expressionBuilder.rbegin() == '*') ) {
expressionBuilder.erase(expressionBuilder.begin());
// can't nicely use rbegin() here because erase() wont take a reverse
// iterator, and converting reverse iterators to regular iterators
// results in rather ugly, non-intuitive code
expressionBuilder.erase(expressionBuilder.end() - 1); // note - not invalid since we're getting it anew
expressionBuilder = "\\b\\w*" + expressionBuilder + "\\w*\\b";
}
Note that this code will work when expressionBuilder
is ""
, "*"
, or "**"
in that it does not perform any undefined actions. However, it might not produce the results you want in those cases (that's because I don't know exactly what you do want in those cases). Modify to suit your needs.
Try erasing them in the opposite order:
expressionBuilder.erase(iter_end);
expressionBuilder.erase(iter_begin);
After erasing the first *, iter_end refers to one character past the end of the string in your example. The STL documentation indicates that iterators are invalidated by erase()
, so technically my example is wrong too but I believe it will work in practice.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With