0

我是正则表达式的新手。我在谷歌上搜索并找到了一些解决方案,然后我想出了自己的解决方案,如下所示

#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;
}

好吧,如果我的字符串包含类似的东西,这段代码就可以正常工作

22-04-2013

它会将其更改为

22/04/2013. 但我希望它是通用的

\d\d-\d\d-\d\d\d\d

替换为

\d\d/\d\d/\d\d\d\d

因为我希望它是通用的。我也在工作linux g++。大多数可用的在线解决方案都在不同的平台上。我还尝试了以下

string toBeReplaced = "\d[-]\d";
&
string replacedWith = "\d/\d";

但没有运气。\d/\d当我进入时我得到了3-4。我不知道为什么。如果我问了一些愚蠢的问题,请原谅我。

编辑

我的问题是匹配一个模式并用一个模式替换它。像数字后跟连字符应替换为数字后跟斜杠。

4

1 回答 1

1

问题

您不能用更多的正则表达式替换匹配项,您将获得文字文本 \d/\d


解决方案

为了实现您的目标,您需要使用反向引用的捕获组()进行替换,如下所示:

(\d{2})-(\d{2})-(\d{4})

您的替换字符串如下所示:

$1/$2/$3

如您所知,每个捕获组都有编号。上述正则表达式中有三个捕获组。


关于捕获组的进一步说明

  • 每当您将表达式包装在(regex)
  • 为了保持你的表达有序,你可以像这样指定非捕获组(?:regex)
  • 为了便于反向引用,请创建一个命名捕获组,如下所示:(?<name>regex)
  • 要在替换字符串中引用命名捕获组,请使用${name},而不是使用$1

请注意,在上面的示例中,regex应替换为您想要的正则表达式。

反向引用的一些语法可能会因不同的正则表达式实现而有所不同,例如:\1而不是$1


示范

这是一个演示,用于直观地表示我正在谈论的内容:

Regex101 示例,在日期时间字符串上捕获组

于 2014-01-15T02:41:12.353 回答