【问题标题】:Perl replacing consecutive blank lines with s/^\s*$/<p>/gmPerl 用 s/^\s*$/<p>/gm 替换连续的空行
【发布时间】:2017-03-06 18:18:04
【问题描述】:

我正在关注关于正则表达式的书,并且有一个例子 有人想用&lt;p&gt; 替换每个连续的空白行。

这是脚本:

undef $/;
$text = <>;

$text =~ s/^\s*$/<p>/gm;

这是输入A\n\n\n\nB\n,与A相同,然后是3个空行,然后是B。

我希望它输出A\n&lt;p&gt;B\n,因为\s 包含换行符,并且在第二行开头和第四行结尾之后重复。

但输出是A\n&lt;p&gt;&lt;p&gt;\nB\n

此外,无论我在AB 之间放了多少空行,我总是得到相同的答案。

但是当输入为A\n\n\n[ ]\nB\n([ ] - 表示空格字符)时,我得到了正确的输出A\n&lt;p&gt;\nB\n,但为什么&lt;p&gt; 之后还有\n

【问题讨论】:

    标签: regex perl


    【解决方案1】:

    这里有两个问题。尾随换行符和两个&lt;p&gt;

    尾随换行

    (?m:$) 匹配换行符之前和字符串末尾。这意味着您替换的文本后面必须跟一个换行符或字符串的结尾。应该使用\n 而不是$

    两个&lt;p&gt;

    这个问题是你的模式能够匹配零个字符的结果。

    Your string:    A␤␤␤␤B␤  
    Positions:      0123456
    

    您的模式找到两个匹配项。

    • 您的模式将从位置 2 开始的 2 个字符替换为 &lt;p&gt;
    • 您的模式将从位置 4 开始的 0 个字符替换为 &lt;p&gt;

    修复:

    s/\n{2,}/\n<p>/g
    

    s/\n\s*\n/\n<p>/g   # Allows whitespace between the newlines.
    

    【讨论】:

    • 我明白了,一开始我以为$ 是在换行符之后,然后我认为^$ 一直被消耗掉了。有人告诉我$ 也可以在\n 之后匹配,这在这种情况下不起作用吗?
    • 我测试了(^\s*$)\n,它也有效。这是更好的解决方案吗?
    • Re "有人告诉我$ 也可以在\n 之后匹配",正如我已经说过的,(?m:$) ($ 当@ 987654341@ 修饰符生效)匹配换行符之前和字符串末尾。 ((?-m:$) 在较少的地方匹配:在字符串末尾的换行符之前和字符串的末尾。)
    • Re "这是更好的解决方案",它的可读性要差得多。目前还不清楚它的作用。事实上,它具有误导性,因为它看起来与一行匹配。
    猜你喜欢
    • 2023-01-30
    • 2012-06-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-03
    相关资源
    最近更新 更多