仅使用捕获的组替换正则表达式

时间:2017-04-03 15:36:32

标签: regex perl sed regex-group

我试图理解为什么以下内容不会给我认为(或想要:))应该返回的内容:

sed -r 's/^(.*?)(Some text)?(.*)$/\2/' list_of_values

或Perl:

perl -lpe 's/^(.*?)(Some text)?(.*)$/$2/' list_of_values

所以我希望我的结果只是Some text ,否则(意味着如果$2中没有捕获任何内容)那么它应该只是空的。

我确实注意到,使用 perl ,如果Some text位于行/字符串的开头(这让我感到困惑......), 就能正常工作。 (另请注意,删除^$无效)

基本上,我尝试使用grep选项获取--only-matching所返回的内容here。只有我想/需要在正则表达式中使用sub / replace。

已编辑(添加样本数据)

示例输入:

$ cat -n list_of_values
     1  Black
     2  Blue
     3  Brown
     4  Dial Color
     5  Fabric
     6  Leather and Some text after that ....
     7  Pearl Color
     8  Stainless Steel
     9  White
    10  White Mother-of-Pearl Some text stuff

期望的输出:

$ perl -ple '$_ = /(Some text)/ ? $1 : ""' list_of_values | cat -n
     1
     2
     3
     4
     5
     6  Some text
     7
     8
     9
    10  Some text

1 个答案:

答案 0 :(得分:4)

首先,this展示了如何使用Perl复制grep -o

你问为什么

foo Some text bar
012345678901234567

只会产生一个空字符串而不是

Some text

那么,

  • 在位置0,^匹配0个字符。
  • 在位置0,(.*?)匹配0个字符。
  • 在位置0,(Some text)?匹配0个字符。
  • 在位置0,(.*)匹配17个字符。
  • 在第17位,$匹配0个字符。
  • 匹配成功。

您可以使用

s{^ .*? (?: (Some[ ]text) .* | $ )}{ $1 // "" }exs;

s{^ .*? (?: (Some[ ]text) .* | $ )}{$1}xs;     # Warns if warnings are on.

更简单:

$_ = /(Some text)/ ? $1 : "";

我质疑你对-p的使用。您确定要为每行输入提供一行输出吗?在我看来,你宁愿拥有

perl -nle'print $1 if /(Some text)/'