?匹配的表达式不在Perl中打印

use*_*392 1 regex perl

我很少写Perl,也不知道如何表达问题。我使用Perl作为浏览文件的“过滤器”。

echo "this is a test" | perl -pe 's/(this).*(test)?/\1 \2/'
Run Code Online (Sandbox Code Playgroud)

仅返回

this
Run Code Online (Sandbox Code Playgroud)

我在寻找

this test
Run Code Online (Sandbox Code Playgroud)

Gri*_*nnz 5

正则表达式(s///运算符第一部分中的功能)与提供的文本顺序地,贪婪地匹配。这意味着它将首先找到this(足够容易),然后.*将匹配字符串的其余部分。(test)?与剩余的字符串匹配,这没有什么,并且由于它是可选的,因此成功。

防止.*在下一部分尝试之前匹配其余字符串的一种方法是使其不贪婪,这是通过附加? 量词修饰符来实现的(不要与?量词混淆,后者意味着零或一)。但这在这里无济于事,因为它只匹配空字符串(它可以匹配的最短字符串),并且之后(test)?也仍然匹配空字符串,因为它不会紧跟在后面test

根据您要尝试执行的操作,有两种可能的解决方案。首先是(test)通过删除来使组成为非可选组?,这将导致匹配尝试越来越小的匹配,.*直到以下文本成功匹配为止(test)(正则表达式功能称为backtracking)。另一种选择是$在非贪心之后将匹配项锚定到字符串的末尾,以便在回退到匹配空字符串之前(通过某种反向回溯).*?,它将始终(test)在字符串的末尾查找。

/(this).*(test)/
/(this).*?(test)?$/
Run Code Online (Sandbox Code Playgroud)

附带说明一下,您的替换变量应为$1and $2,而不是\1and \2; 反斜杠变量用于正则表达式本身,并且仅在sed中受支持,才在替换中使用它们。