【问题标题】:QRegularExpression match patternQRegularExpression 匹配模式
【发布时间】:2017-12-08 00:53:12
【问题描述】:

我想QRegularExpressionMatch在以下情况下返回true:

  • 字符串 开头 FO 。 "FO 后面有一个空格"
  • 字符串开始以@FOOB。
  • 字符串包含 FOOBAR。

所以,我做到了:

QRegularExpression rx("(^(\\bFO\\s\\b|\\@\\bFOOB\\b)) | (\\bFOOBAR\\b)");

QString string0 = "Anywhere FOOBAR in the string";
QString string1 = "FO in the beginning";
QString string2 = "@FOOB in the beginning";

QRegularExpressionMatch match = rx.match(string1);
if (match.hasMatch())
    QTextStream(stdout) << match.captured(0) << endl;

在上面的代码中,有三种模式。第一个和第二个匹配 FO 和 @FOOB 的字符串开头,第三个模式匹配字符串中的任何位置。
如果没有第三种模式,代码对于 string1 和 string2 工作正常。对于第三种模式,它仅适用于 string0 和 string2 而不适用于 string1。我猜 FO 后的空格与第三个模式不匹配,那么所有匹配都失败了?有| [first, second] 和第三个模式之间的运算符!
或者我错过了什么,有人可以帮忙吗? 谢谢!

编辑: 在我发帖 30 秒后找到解决方案:这些额外的空间是问题

QRegularExpression rx("(^(\\bFO\\s\\b|\\@\\bFOOB\\b)) | (\\bFOOBAR\\b)");  
                                                     ^ ^ 

但我不相信!那我们为什么要用括号呢?

【问题讨论】:

    标签: c++ regex qt


    【解决方案1】:

    简介

    正如您所提到的,您的正则表达式中有空格,这就是您的正则表达式不起作用的原因。此解决方案减少了返回匹配项所需的步骤数。

    代码

    如果您只想确保字符串有效,可以使用下面的正则表达式。请注意,如果\s 是绝对必需的(并且在^FO 选项之后没有足够的单词边界\b,您可以简单地将其添加到下面的正则表达式中,以便FO 变为FO\s

    See regex in use here

    ^(?:@FOOB|FO|.*\bFOOBAR)\b.*
    

    如果您正在查找有效字符串并尝试返回匹配项,则可以改用以下正则表达式。

    (?:^(?:@FOOB|FO)|\bFOOBAR)\b
    

    结果

    输入

    Anywhere FOOBAR in the string
    FO in the beginning
    @FOOB in the beginning
    FOOBAR is in the string
    In the string is FOOBAR
    @FOOBAR is valid because foobar (uppercase) exists
    
    Anywhere FOOBARY in the string
    Anywhere FOOBA in the string
    FOO is not a valid start
    @FOOBA is not a valid start
    The @FOOB is not at the start
    

    输出

    以下仅显示匹配项

    Anywhere FOOBAR in the string
    FO in the beginning
    @FOOB in the beginning
    FOOBAR is in the string
    In the string is FOOBAR
    @FOOBAR is valid because foobar (uppercase) exists
    

    说明

    • ^ 在行首断言位置
    • (?:@FOOB|FO|.*\bFOOBAR)非捕获组匹配以下任一
      • @FOOB 从字面上匹配这个
      • FO 从字面上匹配这个
      • .*\bFOOBAR 匹配以下
        • .* 任意字符任意次数
        • \b 将位置断言为单词边界
        • FOOBAR 按字面意思匹配
    • \b 将位置断言为单词边界
    • .* 匹配任意字符任意次数

    【讨论】:

    • 太棒了!,你能编辑解释并添加它是什么意思吗?和:一开始?
    • @Phiber 我已将其添加到我的解释中。这是一个非捕获组。基本上,它不会捕获括号() 中的任何匹配项。它用于分隔逻辑,就像在 if 语句中一样。在这种情况下,它被用来表示匹配这个,或者这个,或者这个(但不要捕获它)
    【解决方案2】:

    您可以在删除不必要的空格后进一步修剪正则表达式:

    QRegularExpression rx("^(?:FO\\s|@FOOB\\b)|\\bFOOBAR\\b");
    

    详情:

    • ^(?:FO\\s|@FOOB\\b) - FO 以及字符串开头的任何空格或整个单词 @FOOB
    • | - 或
    • \\bFOOBAR\\b - 一个完整的词FOOBAR

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多