我找到了一种方法,但我不明白这个原则:
#remove lines starting with //
$file =~ s/(?<=\n)[ \t]*?\/\/.*?\n//sg;
(?<=\n)[ \t]*?
如何运作?
答案 0 :(得分:3)
关键部分是lookbehind (?<=...)
。它是零宽度断言,这意味着它不消耗它的匹配 - 它只断言内部给出的模式确实在字符串中,就在它后面的模式之前。
因此(?<=\n)[ \t]
匹配空格或制表符[ \t]
,前面有换行符。使用量词[ \t]*
,它可以任意次数(可能为零)匹配空格或制表符。然后我们有//
(每个都被\
转义)。然后它会匹配任何字符,直到第一个换行符.*?\n
为止。
此处?
使.*
非贪婪,以便在以下模式的第一个匹配时停止。
这也可以通过其他方式完成。
$file =~ s{ ^ \s* // .*? \n }{}gmx
修饰符m
使锚点^
和$
(此处未使用)匹配每个行的开头和结尾。我使用{}{}
作为分隔符,以便我不必逃避/
。修饰符x
允许在内部使用空格(以及注释和换行符)以便于阅读。
你也可以通过split来执行此操作 - 按换行符表示字符串并通过grep传递行
my $new_file = join '\n', grep { not m|^\s*//.*| } split /\n/, $file;
split
返回一个行列表,这是grep
的输入,它将块中代码所评估的那些值传递给true。如果您希望再次拥有多行字符串,则返回它返回的列表。
如果您想要删除行join '\n'
并将其分配给数组。
grep
块中的正则表达式现在变得更加简单了,但与之前的正则表达式相比,整个事情可能会让人眼前一亮。然而,这种方法可以将艰苦的工作变成简单的工作:而不是去寻找怪物大师正则表达式,打破字符串并轻松处理它们。