【问题标题】:boost::regex - \bb?boost::regex - \bb?
【发布时间】:2010-11-29 14:48:32
【问题描述】:

我这里有一些使用boost::regex::perl 的旧代码,注释很差。之前我想知道一个特定的结构,但由于代码(或多或少)有效,我不愿意碰它。

现在我必须触摸它,出于技术原因(更准确地说,当前版本的 Boost 不再接受该构造),所以我必须弄清楚它做了什么 - 或者更确切地说,是打算这样做的。

正则表达式的相关部分:

(?<!(\bb\s|\bb|^[a-z]\s|^[a-z]))

让我头疼的是\bb。我知道\b,但我找不到提到\bb,在这里寻找文字'b' 是没有意义的。 \bb 是一些特殊的未充分记录的功能,还是我必须认为这是一个错字?

【问题讨论】:

  • 你能不能简单地试试\bb是否匹配“b”(而不是“a”)来检查它是否真的做除了单词边界之外的任何事情,然后是“b”?
  • 嗯,问题 - 与所有未注释的代码一样 - 是它所做的 可能实际上与它打算 要做的事情无关。我必须针对旧的 (1.34.1) 和当前的 Boost 版本对其进行测试,并且 仍然 必须猜测作者的意图......
  • 阅读源代码,卢克(boost::regex::perl 就是......祝你好运:)
  • 如果\bb 有特殊含义,那么你将如何指定一个字边界,然后是b
  • @mobrule: 嗯...哦。好点。 :-D

标签: c++ regex perl boost


【解决方案1】:

Boost 似乎是 C++ 的正则表达式引擎,而 一种 兼容模式是 perl 兼容性——如果这是一个“perl 兼容”表达式,那么第二个 'b ' 只能 是文字。

这是一个有效的表达式,几乎是一个以 'b' 开头的单词的特殊情况。

这似乎是决定因素,这是一个 c++ 库,并且它提供了 不是 perl、perl 兼容的正则表达式的环境。因此,我最初认为 perl 可能会解释表达式(比如overload::constant)是无效的。然而,为了澄清的目的,仍然值得一提,无论调整一个表示“以'b'开头的单词”的表达是多么不可取。

对这个想法的唯一警告是,也许Boost 在它自己的表达式上优于 Perl,并且有人会在 Perl 环境中使用 Boost 引擎,然后所有关于这是否可能是一种特殊表达的赌注已经结束。这只是一个刺,给定一个语法,其中 '!!!'在单词的开头意味着一些特别的东西,你可以像这样捎带既定的意思(不推荐!)

s/\\bb\b/(?:!!!(\\p{Alpha})|\\bb)/

这将是一件愚蠢的事情,但是当我们处理看起来不适合其任务的代码时,有数千种方法会导致任务失败。

【讨论】:

    【解决方案2】:

    (\bb\s|\bb|^[a-z]\s|^[a-z]) 匹配 b 如果它前面没有另一个单词字符,或者 any 小写字母如果它位于字符串的开头。在任何一种情况下,该字母都可以后跟一个空白字符。 (如果设置了不区分大小写模式,它也可以匹配大写字母,如果设置了多行模式,^ 也可以匹配行首。)

    但是在一个lookbehind里面,它甚至不应该被编译。在某些风格中,lookbehind 可以包含多个具有不同固定长度的替代方案,但交替必须位于lookbehind 的顶层。也就是说,(?&lt;=abc|xy|12345) 会起作用,但(?&lt;=(abc|xy|12345)) 不会。因此,即使在 那些 风格中,您的正则表达式也无法工作,但 Boost 的文档只是说后向表达式必须是固定长度的。

    如果您确实需要考虑该正则表达式匹配的所有四种可能性,我建议您将后视分成两部分:

    (?<!\bb|^[a-z])(?<!(?:\bb|^[a-z])\s)
    

    【讨论】:

    • +1 指出“交替必须位于后视的顶层”。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-24
    • 2017-12-19
    • 2011-12-09
    相关资源
    最近更新 更多