我的正则表达式在块的开头查找左大括号不起作用

问题描述 投票:0回答:2

大约一周前我才开始学习 perl。但我对正则表达式功能有基本的了解,比如反向引用、环顾四周等。 所以我写了一个小的正则表达式来匹配数组中的字符串(这个数组代表文件的每一行)只有'{'作为可打印字符。

我的正则表达式是这样的:

for my $f_line (@file_lines) {
    my @opening_brace;
    if ($f_line =~ /(^[[:blank:]]*(?={))({[[:blank:]]*$)/) {
      @opening_brace = $2;
      print "opening brace : @opening_brace \n"; 
    }
  }

但是,我的正则表达式无法让我进入 if 块,即使它在

grep
上运行良好,当我针对目标文件进行测试时。

我做错了什么?

我试过:

echo "{       " | grep -P '(^[[:blank:]]*(?={))({[[:blank:]]*$)'

得到:

{

regex bash perl grep backreference
2个回答
0
投票

哦 我刚刚找到了一个修复程序。 看来我的文件“行”并不是真正的行。 问题在于字符串的逻辑行和文字锚点之间的细微差别,这些锚点表示文件行的开头和结尾,这些锚点是在我将行作为字符串推入数组时创建的。 谢谢你的帮助


0
投票

这里逐字复制的正则表达式有效

echo "{   " | perl -wnlE'say $1 if /^[[:blank:]]*(?={)({[[:blank:]]*$)/'

打印一行:

{

但是没有

$2
,在问题中使用,因为显示的正则表达式只捕获一次。似乎您希望前瞻的
(?=...)
也能捕获:它没有。我们需要额外的括号,
(?=({))
。因此,要么将其添加到您的正则表达式中,要么保持正则表达式不变并在代码中使用
$1
。 (除非数据本身实际上与问题所暗示的不同。)

然后,我不明白为什么要使用前瞻 and 然后为该模式进行实际的消费匹配。 (练习?)


在评论中提到输入可能包含换行符,例如

{\n
。上面使用的问题中的正则表达式仍然有效。

很容易看到的一种方法是删除

-l
开关(所以使用
-wnE
),
chomp
是换行符。然后将正则表达式应用于以换行符结尾的字符串,添加
echo
——我们仍然得到匹配和捕获。 ([[:blank:]]
POSIX 字符类
不匹配换行符。)


一般说明。问题中的

$2
assigned 给一个数组,如
@opening_brace = $2
can 完成后,数组就有了那个元素。然而,这是非常具有误导性的,并且分配给一个数组会覆盖其中可能已经存在的内容。

我们通过

push @arrayname, LIST
添加到数组,所以在这种情况下是
push @opening_brace, $2;
(但请参阅上面关于
$2
的讨论)。或者,如果数组的字符
@opening_brace
错误地存在,则将
$opening_brace
更正为标量
@

© www.soinside.com 2019 - 2024. All rights reserved.