草庐IT

c++11 正则表达式和 GCC

coder 2024-02-26 原文

根据 https://gcc.gnu.org/onlinedocs/libstdc++/manual/status.html#status.iso.2011 C++11标准的正则表达式引擎应该在GCC中完成。现在,有人可以向我解释为什么这个简单的例子

#include <iostream>
#include <string>
#include <regex>


using namespace std;


int main ()
{
    string string_array[] = {"http://www.cplusplus.com/reference/regex/regex_match/",
                             "tcp://192.168.2.1:1234/hello/how/are/you",
                             "https://mail.google.com/mail/u/0/?tab=wm#inbox/15178022db56df29?projector=1"};
    regex e("^(?:([A-Za-z]+):)?(\\/{0,3})([0-9.\\-A-Za-z]+)(?::(\\d+))?(?:\\/([^?#]*))?(?:\\?([^#]*))?(?:#(.*))?$");

    for(int i=0; i<3; i++)
    {
        smatch sm;
        regex_match (string_array[i],sm,e);

        for (unsigned i=0; i<sm.size(); ++i)
        {
            cout << "[" << sm[i] << "] ";
        }

        cout << endl;
    }
    return 0;
}

结果是这个输出(例如注意第二行错误解析的端口号,但似乎有很多错误)

[http://www.cplusplus.com/reference/regex/regex_match/] [http] [//] [www.cplusplus.com/reference/regex] [] [regex_match/] [] [] 
[tcp://192.168.2.1:1234/hello/how/are/you] [tcp] [//] [192.168.2.1:1234/hello/how/are/you] [] [] [] [] 
[https://mail.google.com/mail/u/0/?tab=wm#inbox/15178022db56df29?projector=1] [https] [//] [mail.google.com/mail/u/0/?tab=wm] [] [] [] [inbox/15178022db56df29?projector=1] 

而它的 python 对应物

import re

string_array = ["http://www.cplusplus.com/reference/regex/regex_match/",
                         "tcp://192.168.2.1:1234/hello/how/are/you",
                         "https://mail.google.com/mail/u/0/?tab=wm#inbox/15178022db56df29?projector=1"]
e = re.compile("^(?:([A-Za-z]+):)?(\\/{0,3})([0-9.\\-A-Za-z]+)(?::(\\d+))?(?:\\/([^?#]*))?(?:\\?([^#]*))?(?:#(.*))?$");

for i in range(len(string_array)):
    m = e.match(string_array[i])
    print(m.groups())

正确打印这个?

('http', '//', 'www.cplusplus.com', None, 'reference/regex/regex_match/', None, None)
('tcp', '//', '192.168.2.1', '1234', 'hello/how/are/you', None, None)
('https', '//', 'mail.google.com', None, 'mail/u/0/', 'tab=wm', 'inbox/15178022db56df29?projector=1')

我在 archlinux 上使用 gcc 5.3.0

编辑:

我把程序改成这样,检查正则表达式 syntax_option_type 标志

#include <iostream>
#include <string>
#include <regex>


using namespace std;


int main ()
{
    string string_array[] = {"http://www.cplusplus.com/reference/regex/regex_match/",
                             "tcp://192.168.2.1:1234/hello/how/are/you",
                             "https://mail.google.com/mail/u/0/?tab=wm#inbox/15178022db56df29?projector=1"};
    regex e("^(?:([A-Za-z]+):)?(\\/{0,3})([0-9.\\-A-Za-z]+)(?::(\\d+))?(?:\\/([^?#]*))?(?:\\?([^#]*))?(?:#(.*))?$");

    for(int i=0; i<3; i++)
    {
        smatch sm;
        cout << "match: " <<regex_match (string_array[i],sm,e) << endl;

        for (unsigned i=0; i<sm.size(); ++i)
        {
            cout << "[" << sm[i].str() << "] ";
        }
    }

    cout << endl;

    switch(e.flags())
    {
        case regex_constants::basic:
            cout << "POSIX syntax was used" << endl;
            break;
        case regex_constants::awk:
            cout << "POSIX awk syntax was used" << endl;
            break;
        case regex_constants::ECMAScript:
            cout << "ECMA syntax was used" << endl;
            break;
        case regex_constants::egrep:
            cout << "POSIX egrep syntax was used" << endl;
            break;
    }

    return 0;
}

令人惊讶的是我最后得到了

match: 1
[http://www.cplusplus.com/reference/regex/regex_match/] [http] [//] [www.cplusplus.com/reference/regex] [] [regex_match/] [] [] match: 1
[tcp://192.168.2.1:1234/hello/how/are/you] [tcp] [//] [192.168.2.1:1234/hello/how/are/you] [] [] [] [] match: 1
[https://mail.google.com/mail/u/0/?tab=wm#inbox/15178022db56df29?projector=1] [https] [//] [mail.google.com/mail/u/0/?tab=wm] [] [] [] [inbox/15178022db56df29?projector=1] 
ECMA syntax was used

这似乎真的是一个编译器错误..

最佳答案

这里有两个问题:

match object groups()在 Python 中返回以组 1 开头的所有子匹配(捕获的子字符串):

Return a tuple containing all the subgroups of the match, from 1 up to however many groups are in the pattern.

match_results从第 0 组(整场比赛)开始枚举所有组:

If successful, it is not empty and contains a series of sub_match objects: the first sub_match element corresponds to the entire match, and, if the regex expression contained sub-expressions to be matched (i.e., parentheses-delimited groups), their corresponding sub-matches are stored as successive sub_match elements in the match_results object.

第 3 组中的 \ 没有转义连字符,它会被忽略,从而在 .A 之间创建一个范围(= [.-A] 在正常的正则表达式世界中)。

您不能在 POSIX 正则表达式的字符类中使用转义符号,这被认为是一个错误。将连字符放在末尾以避免对其进行转义(如 [0-9.A-Za-z-]+)。

因此,在 Python 中,使用

e = re.compile("^(?:([A-Za-z]+):)?(\\/{0,3})([0-9.A-Za-z-]+)(?::(\\d+))?(?:\\/([^?#]*))?(?:\\?([^#]*))?(?:#(.*))?$");

在 C++ 中:

regex e("^(?:([A-Za-z]+):)?(\\/{0,3})([0-9.A-Za-z-]+)(?::(\\d+))?(?:\\/([^?#]*))?(?:\\?([^#]*))?(?:#(.*))?$");
// ...
for(int i=0; i<3; i++)
{
    smatch sm;
    regex_match (string_array[i],sm,e);

    for (unsigned i=1; i<sm.size(); ++i) // Here, start with the second element
    {
        cout << "[" << sm[i] << "] ";
    }

    cout << endl;
}

比较 Python demoC++ demo .

关于c++11 正则表达式和 GCC,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34321129/

有关c++11 正则表达式和 GCC的更多相关文章

  1. ruby-on-rails - 如何优雅地重启 thin + nginx? - 2

    我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server

  2. ruby 正则表达式 - 如何替换字符串中匹配项的第 n 个实例 - 2

    在我的应用程序中,我需要能够找到所有数字子字符串,然后扫描每个子字符串,找到第一个匹配范围(例如5到15之间)的子字符串,并将该实例替换为另一个字符串“X”。我的测试字符串s="1foo100bar10gee1"我的初始模式是1个或多个数字的任何字符串,例如,re=Regexp.new(/\d+/)matches=s.scan(re)给出["1","100","10","1"]如果我想用“X”替换第N个匹配项,并且只替换第N个匹配项,我该怎么做?例如,如果我想替换第三个匹配项“10”(匹配项[2]),我不能只说s[matches[2]]="X"因为它做了两次替换“1fooX0barXg

  3. ruby-on-rails - 无法在centos上安装therubyracer(V8和GCC出错) - 2

    我正在尝试在我的centos服务器上安装therubyracer,但遇到了麻烦。$geminstalltherubyracerBuildingnativeextensions.Thiscouldtakeawhile...ERROR:Errorinstallingtherubyracer:ERROR:Failedtobuildgemnativeextension./usr/local/rvm/rubies/ruby-1.9.3-p125/bin/rubyextconf.rbcheckingformain()in-lpthread...yescheckingforv8.h...no***e

  4. ruby - 使用 `+=` 和 `send` 方法 - 2

    如何将send与+=一起使用?a=20;a.send"+=",10undefinedmethod`+='for20:Fixnuma=20;a+=10=>30 最佳答案 恐怕你不能。+=不是方法,而是语法糖。参见http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_expressions.html它说Incommonwithmanyotherlanguages,Rubyhasasyntacticshortcut:a=a+2maybewrittenasa+=2.你能做的最好的事情是:

  5. ruby - 安装libv8(3.11.8.13)出错,Bundler无法继续 - 2

    运行bundleinstall后出现此错误:Gem::Package::FormatError:nometadatafoundin/Users/jeanosorio/.rvm/gems/ruby-1.9.3-p286/cache/libv8-3.11.8.13-x86_64-darwin-12.gemAnerroroccurredwhileinstallinglibv8(3.11.8.13),andBundlercannotcontinue.Makesurethat`geminstalllibv8-v'3.11.8.13'`succeedsbeforebundling.我试试gemin

  6. ruby - 正则表达式将非英文字母匹配为非单词字符 - 2

    @raw_array[i]=~/[\W]/非常简单的正则表达式。当我用一些非拉丁字母(具体来说是俄语)尝试时,条件是错误的。我能用它做什么? 最佳答案 @raw_array[i]=~/[\p{L}]/使用西里尔字符进行测试。引用:http://www.regular-expressions.info/unicode.html#prop 关于ruby-正则表达式将非英文字母匹配为非单词字符,我们在StackOverflow上找到一个类似的问题: https://

  7. ruby - 正则表达式在哪个位置失败? - 2

    我需要一个非常简单的字符串验证器来显示第一个符号与所需格式不对应的位置。我想使用正则表达式,但在这种情况下,我必须找到与表达式相对应的字符串停止的位置,但我找不到可以做到这一点的方法。(这一定是一种相当简单的方法……也许没有?)例如,如果我有正则表达式:/^Q+E+R+$/带字符串:"QQQQEEE2ER"期望的结果应该是7 最佳答案 一个想法:你可以做的是标记你的模式并用可选的嵌套捕获组编写它:^(Q+(E+(R+($)?)?)?)?然后你只需要计算你获得的捕获组的数量就可以知道正则表达式引擎在模式中停止的位置,你可以确定匹配结束

  8. ruby - 如何计算 Liquid 中的变量 +1 - 2

    我对如何计算通过{%assignvar=0%}赋值的变量加一完全感到困惑。这应该是最简单的任务。到目前为止,这是我尝试过的:{%assignamount=0%}{%forvariantinproduct.variants%}{%assignamount=amount+1%}{%endfor%}Amount:{{amount}}结果总是0。也许我忽略了一些明显的东西。也许有更好的方法。我想要存档的只是获取运行的迭代次数。 最佳答案 因为{{incrementamount}}将输出您的变量值并且不会影响{%assign%}定义的变量,我

  9. ruby - 有没有办法从 ruby​​ case 语句中访问表达式? - 2

    我想从then子句中访问c​​ase语句表达式,即food="cheese"casefoodwhen"dip"then"carrotsticks"when"cheese"then"#{expr}crackers"else"mayo"end在这种情况下,expr是食物的当前值(value)。在这种情况下,我知道,我可以简单地访问变量food,但是在某些情况下,该值可能无法再访问(array.shift等)。除了将expr移出到局部变量然后访问它之外,是否有直接访问caseexpr值的方法?罗亚附注我知道这个具体示例很简单,只是一个示例场景。 最佳答案

  10. ruby - 正则表达式 - 排除一个字符 - 2

    这是一个例子:s="abcd+subtext@example.com"s.match(/+[^@]*/)Result=>"+subtext"问题是,我不想在其中包含“+”。我希望结果是“潜台词”,没有+ 最佳答案 您可以在正则表达式中使用括号来创建匹配组:s="abcd+subtext@example.com"s=~/\+([^@]*)/&&$1=>"subtext" 关于ruby-正则表达式-排除一个字符,我们在StackOverflow上找到一个类似的问题:

随机推荐