【问题标题】:Regex for different newlines不同换行符的正则表达式
【发布时间】:2017-05-06 16:07:39
【问题描述】:

假设我有一个文本,表示为 std::string,其中包含几个不同的换行符,例如\r\n 但也只是 \n 甚至只是 \r。

我现在想通过替换所有非 \r\n 换行符来统一这一点,即用 \r\n 替换所有 \r 和所有 \n 换行符。

一个简单的 boost::replace_all(text, "\n", "\r\n");不幸的是,这不起作用,因为这也会替换已经有效的 \r\n 中的 \n。

我认为 std::regex 应该是处理这个问题的好方法......但是我应该如何在正则表达式中表达这个?这是一些代码:

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

int main()
{
    std::string text = "a\rb\nc\r\nd\n";
    std::regex reg(""); // What to put here?
    text = std::regex_replace(text, reg, "\r\n");
    std::cout << text;
}

文本最后应该是"aaa\r\nbbb\r\nccc\r\nddd\r\n"

【问题讨论】:

    标签: c++ regex c++11


    【解决方案1】:
    std::regex_replace(text, reg, "\r\n|\r|\n");
    

    应该匹配。

    更多信息在这里:

    Match linebreaks - \n or \r\n?

    【讨论】:

    • 更好的模式是\r\n?|\n。作为最佳做法,备选方案应在不同位置匹配。
    • @WiktorStribiżew:“更好”的衡量标准是什么? “备选方案应在不同位置匹配”是什么意思?
    • 性能更好,当然不是外观。用手机打字很难。我的意思是:“最好的做法是编写替代方案,使它们不能在字符串中的同一位置匹配。”这样您就可以摆脱不必要的回溯。
    【解决方案2】:

    您可以分两步完成:

    1. \n -> \r\n
    2. \r\r\n -> \r\n

    或一步到位:

    (?:\r\n|\n|\r) -> \r\n

    #include <iostream>
    #include <string>
    #include <regex>
    
    int main()
    {
        std::string text = "a\rb\nc\r\nd\n";
        text = std::regex_replace(text, std::regex("(?:\\r\\n|\\n|\\r)"), "\r\n");
        std::cout << text;
    }
    

    【讨论】:

      【解决方案3】:

      要将“\n”与前面没有“\r”交换,您实际上可以使用前瞻:

      std::regex_replace("\n\n\n\n\n", std::regex("[^\r](?=\n)"), "$1\r\n");
      

      这不能处理文件的最后一个新行,所以你需要另一个操作。

      交换“\r”而不跟随“\n”要容易一些:

      std::regex_replace(text, std::regex("\r[^\n]"), "\r\n");
      

      请注意,根据 c++ 正则表达式的风格,如果您正在考虑它,那么您很有可能无法支持向后看。

      【讨论】:

      • 代码无法编译。我用 std::regex() 包装了“([^\r])\n”。它可以编译,但不能正确处理“\n\n”。代码将“\n\n”翻译成“\r\n\n”。
      • @HarryLeong 4 年后,终于有人喊国王赤身裸体了!谢谢,你在所有方面都是对的 - 让我想知道谁赞成这些答案。我会修改它。
      • 感谢您的回复。在您确认之前,这些赞成票确实让我怀疑自己。
      【解决方案4】:

      \R 代表任何类型的换行符,即:\n\r\r\n

      【讨论】:

      • 这似乎不起作用,我使用 std::regex reg("\\R");但是原始字符串中没有任何内容被替换...
      猜你喜欢
      • 2022-10-13
      • 2011-06-29
      • 2014-06-30
      • 1970-01-01
      • 1970-01-01
      • 2014-03-10
      • 2012-04-08
      • 2011-07-01
      • 1970-01-01
      相关资源
      最近更新 更多