使用正则表达式从 Perl 中的字符串中删除额外的管道和它们周围的文本

Sol*_*Sol 1 regex perl

假设我有一个像这样的字符串,我想在 perl 中进行处理。

hello|world|nice|to|meet|you
Run Code Online (Sandbox Code Playgroud)

我想保留前三个管道符号和它们周围的文本并丢弃字符串的其余部分。所以,我最终会这样:

hello|world|nice|to
Run Code Online (Sandbox Code Playgroud)

我想我想做这样的事情:

substitute (zero or more non-pipes followed by a pipe)[3 times] followed by the rest of the string with a back reference to the piece of the regex where I matched the 3 pipes and the characters around them. 
Run Code Online (Sandbox Code Playgroud)

我不确定 perl 中的正则表达式语法。

我可以做我想做的事:

$str = "hello|world|nice|to|meet|you" ;
@a = split(/\|/, $str) ;
print $a[0] . "|" . $a[1] . "|" . $a[2] . "|" . $a[3]
Run Code Online (Sandbox Code Playgroud)

但是,我想看看如何用正则表达式来做到这一点。

anu*_*ava 6

您可以使用此正则表达式:

s='hello|world|nice|to|meet|you'
perl -pe 's/^((?:[^|]*\|){3}[^|]*).*/$1/' <<< "$s"
Run Code Online (Sandbox Code Playgroud)

hello|world|nice|to
Run Code Online (Sandbox Code Playgroud)

正则表达式详情:

  • ^: 开始
  • (:开始捕获组#1
    • (?:: 启动非捕获组
      • [^|]*: 匹配 0 个或多个非管道字符
      • \|: 匹配一个管道
    • ){3}: 结束非捕获组。{3}匹配该组的 3 次重复
    • [^|]*: 匹配 0 个或多个非管道字符
  • ): 结束捕获组#`
  • .*:匹配所有内容直到结束

Perl 代码

$str = "hello|world|nice|to|meet|you" ;

$str =~ s/^((?:[^|]*\|){3}[^|]*).*/$1/;

print "$str\n";
Run Code Online (Sandbox Code Playgroud)