I am new to regular expressions. I was googling and found some solutions and then I come up with my own solution as following
#include <string.h>
#include <regex.h>
#include <iostream>
int rreplace (char *buf, int size, regex_t *re, char *rp){
char *pos;
int sub, so, n;
regmatch_t pmatch [10];
if (regexec (re, buf, 10, pmatch, 0))
return 0;
for (pos = rp; *pos; pos++)
if (*pos == '\\' && *(pos + 1) > '0' && *(pos + 1) <= '9'){
so = pmatch [*(pos + 1) - 48].rm_so;
n = pmatch [*(pos + 1) - 48].rm_eo - so;
if (so < 0 || strlen (rp) + n - 1 > size)
return 1;
memmove (pos + n, pos + 2, strlen (pos) - 1);
memmove (pos, buf + so, n);
pos = pos + n - 2;
}
sub = pmatch [1].rm_so; /* no repeated replace when sub >= 0 */
for (pos = buf; !regexec (re, pos, 1, pmatch, 0); ){
n = pmatch [0].rm_eo - pmatch [0].rm_so;
pos += pmatch [0].rm_so;
if (strlen (buf) - n + strlen (rp) + 1 > size)
return 1;
memmove (pos + strlen (rp), pos + n, strlen (pos) - n + 1);
memmove (pos, rp, strlen (rp));
pos += strlen (rp);
if (sub >= 0)
break;
}
return 0;
}
int main (int argc, char **argv){
//buf [FILENAME_MAX],
char rp [FILENAME_MAX];
regex_t re;
string toBeReplaced = "-";
string replacedWith = "/";
regcomp (&re, toBeReplaced.c_str(), REG_ICASE);
string buf;
cout << "Enter date separated with dash" << endl;
cin >> buf;
char * replacedWith_ = new char[replacedWith.size() + 1];
std::copy(replacedWith.begin(), replacedWith.end(), replacedWith_);
replacedWith_[replacedWith.size()] = '\0'; // don't forget the terminating 0
char * buf_ = new char[buf.size() + 1];
std::copy(buf.begin(), buf.end(), buf_);
buf_[buf.size()] = '\0'; // don't forget the terminating 0
rreplace (buf_, FILENAME_MAX, &re, strcpy (rp, replacedWith_));
cout<< buf_ << endl;
regfree (&re);
delete[] replacedWith_;
return 0;
}
Well this code works fine if my string contains something like
22-04-2013
and it will change it to
22/04/2013
. but I want it to be generic something like
\d\d-\d\d-\d\d\d\d
to be replaced with
\d\d/\d\d/\d\d\d\d
as I want it to be generic. Also I am working in linux g++
. Most of the on-line solutions available are on different platforms. I also tried the following
string toBeReplaced = "\d[-]\d";
&
string replacedWith = "\d/\d";
but no luck. and I get \d/\d
when I enter 3-4
. I dont know why. Forgive me if I asked something stupid.
EDIT
My problem is match a pattern and replace it with a pattern. like digit followed by a hyphen should be replaced with digit followed by a slash.
You cannot replace a match with more regex, you will get the literal text \d/\d
instead.
To accomplish your goal, you need replace using a backreferenced capture group()
like so:
(\d{2})-(\d{2})-(\d{4})
Your replacement string would be as follows:
$1/$2/$3
As you can tell, each capture group is numbered. There are three capture groups in the above regex.
(regex)
(?:regex)
(?<name>regex)
${name}
, instead of using $1
Please note in the above examples, regex
should be replaced by your desired Regular Expression.
Some syntax for backrefencing may vary with different Regex Implementations, for example: \1
instead of $1
Here's a demo for a visual representation of what I'm talking about: