【问题标题】:Matching "beginning-of-line" using libc++ regex library (C++11)使用 libc++ 正则表达式库 (C++11) 匹配“行首”
【发布时间】:2012-08-14 20:05:29
【问题描述】:

我想匹配所有以给定单词开头的行,比如 iheap。如果我没记错的话,正则表达式(在 ECMAScript 语法中)"^iheap.*" 应该可以解决问题。但是,当我使用 libc++ 的 regex 库在 C++11 中对此进行测试时,只有第一行匹配。所以"^..." 似乎只匹配输入开头而不是行开头。

这是一个例子:

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

using namespace std;

int main() {
        regex rx("^iheap.*");
        string s = "iheap says hello.\niheap says hello again.\n";
        cout << s << regex_replace(s, rx, "IHEAP");
        return 0;
}

输出:

iheap says hello.
iheap says hello again.
IHEAP
iheap says hello again.

这是 libc++ 的错误还是我做错了什么?谢谢!

注意:我使用的是 Mac OS X Mountain Lion 和 Apple LLVM Compiler 4.0(基本上是 clang 3.1 SVN 的快照)。

【问题讨论】:

  • 刚刚偶然发现这个问题...仅供参考,boost::regex(在 EMCAScript 模式下)匹配行首,即您的正则表达式可以工作。
  • 嗯,只是稍微相关,但$ 与 VS2013 中的 \r\n 不匹配——它需要 \s*$ 或类似的匹配...

标签: c++ regex c++11 clang libc++


【解决方案1】:

我查看了所有相关标准,据我所知,^ 仅匹配字符串的开头,而不匹配换行符,除非引擎处于 multiline 模式.默认引擎是ECMA-262 该引擎默认不处于多行模式,我看不到使用标准C++接口将其置于多行模式。

话虽如此,如果有人能指出我所说的不同的规范性文本,我会认为这是一个错误报告并尽我所能修复它。

【讨论】:

  • 只是为了一笑而过,试试这个:(?m)^iheap.*。 ECMA-262 没有指定内联修饰符,但libc++ 可能无论如何都支持它们。这不会是唯一的 ECMAScript 正则表达式实现单方面添加对规范中未涵盖的功能的支持。
  • 你好霍华德。我也找不到解决问题的规范性文本,但我认为我有足够的理由暗示默认模式应该是多行的。有std::regex_constants::match_not_bol 标志,其功能是确保"^" 断言与输入的开头不匹配。在多行模式下使用该标志; "^" 断言将匹配除第一行之外的所有行。在单行模式下,该标志将使"^" 断言不起作用,这对我来说没有意义。
  • 我找到了两个支持我的解释的非官方参考网站。查看this website"^" 断言的解释和this websitematch_not_bol 标志的解释。我知道这些不是规范性文本,但它们提供了一些证据,证明许多人期望这种多行行为是默认的。请注意,"$" 断言也存在同样的问题(并且有一个相应的标志 match_not_eol)。
  • 我会调查的。感谢您的调查。
  • 该标准对此只字未提,但我所知道的其他 2 个工作实现(boost::regex 和 Visual Studio 2012)将 ^ 和 $ 与换行符匹配。
【解决方案2】:

此问题已在 http://cplusplus.github.io/LWG/lwg-toc.html 的 2343 列出。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-10
    • 2017-11-13
    • 1970-01-01
    相关资源
    最近更新 更多