【问题标题】:GNU sed, ^ and $ with | when first/last character matchesGNU sed、^ 和 $ 与 |当第一个/最后一个字符匹配时
【发布时间】:2017-02-10 00:35:01
【问题描述】:

当在 REGEXP 中进行包含 ^|. 之类的替换时,如果第一个字符匹配,则 sed 与模式空间开头的空字符串不匹配。如果最后一个字符匹配,它也不匹配结尾。这是为什么呢?

以下是一些使用123 作为输入的示例(使用-r 选项):

substitution    expected output     actual output   comments
s/^/x/g         x123                x123            works as expected
s/$/x/g         123x                123x            works as expected
s/^|$/x/g       x123x               x123x           works as expected
s/^|./x/g       xxxx                xxx             didn't match the very begining
s/.|$/x/g       xxxx                xxx             didn't match the very end
s/^|1/x/g       xx23                x23             didn't match the very begining
s/^|2/x/g       x1x3                x1x3            this time it did match the begining

使用 \` 而不是 ^ 时,我得到了相同的结果。
我试过 GNU sed 版本 4.2.1 和 4.2.2

Try it online!

【问题讨论】:

    标签: bash sed gnu-sed


    【解决方案1】:

    AFAIK sed 将尝试交替匹配最长的匹配项。

    所以当模式空间开头的空字符串可以与1在同一位置匹配时。 1 被选中,因为它是最长的匹配项。

    考虑以下几点:

    $ sed 's/12\|123/x/g' <<< 123
    x
    $ sed 's/123\|12/x/g' <<< 123
    x
    $ sed 's/^1\|12/x/g' <<< 123
    x3
    

    到达终点时也是如此。让我们打破sed 's/.\|$/x/g' &lt;&lt;&lt; 123

    123
    ^
    . matches and replace with x
    x23
     ^
     . matches and replace with x
    xx3
      ^
      . matches and replace with x
    xxx
       ^
       Out of pattern space $ will not match.
    

    【讨论】:

    • 所以它不会将开头的空字符串视为在它自己的位置?在某种程度上它是第一个字符的一部分?
    • ^匹配所述的空字符串,匹配的长度为0,而第一个位置的1的长度为1。所以替换。两者都会匹配,但只会替换最长的。
    • 为什么不把它们都替换掉? sed 's/12\|123/x/g &lt;&lt;&lt;12123 替换 12123,即使 123 更长。
    • 您的示例不同,因为 12 匹配并替换然后 123。考虑一下:sed 's/11\|111//g' &lt;&lt;&lt; 1111。更换后还剩多少。零还是一?
    • 为什么s/^|1/x/g &lt;&lt;&lt; 123s/1|2/x/g &lt;&lt;&lt; 123 不同?第二个替换 1 然后 2,不应该第一个替换空字符串然后 1?
    猜你喜欢
    • 2014-02-07
    • 2013-09-07
    • 2014-08-12
    • 1970-01-01
    • 2016-09-19
    • 1970-01-01
    • 2016-01-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多