我正在尝试使用单行正则表达式在文件中进行替换。 sed 失败了,所以我转向 Perl。例如,我可以匹配“setting = value # comment”并将其提取为三个部分“setting =”、“value”和“# comment”。
例如:
perl -lne 'print "-1-$1-2-$2-3-$3-E-" if /^\s*(setting\s*=\s*)([^\s#]+)(\s*#\s*.*)?/'
我会看到类似的结果
-1-setting = -2-value-3- # comment-E-
现在问题出现了,值可能会用引号引起来,无论是单引号还是双引号,简单的
'
或 '"
字符。不偏不倚,开闭形式相同。
使用反向引用来检测匹配的引号是很诱人的:
perl -lne 'print "-1-$1-2-$2-3-$3-4-$4-5-$5-E-" if /^\s*(setting\s*=\s*)(\N{APOSTROPHE}|\N{QUOTATION MARK})?([^\s#]+)(\2)?(\s*#\s*.*)?/'
这里的问题是第 3 组捕获收盘价,而第 4 组为空。
在这里我们遇到了一个问题。我们不能添加对组 3 的否定断言的反向引用,perl 不支持这一点,原因很简单,捕获组不是一个字符(或者不能保证是一个字符,即使我们的是一个字符)。
所以这就提出了一个难题。有没有办法在 Perl 正则表达式中捕获这些可选的匹配引号?
到目前为止,我的思考、阅读和实验使我考虑以下可能性:
对字符串而不是字符的否定断言。我们有
[abc]
匹配 a、b 或 c,我们有 [^abc]
匹配任何不是 a、b 或 c 的字符,还有 (string1|string2|string3)
匹配 string1、string2 或 string3 中的任何一个。但是该断言是否有否定形式,即不是 string1、string2 或 string3 的任何 strig?
创建一个字符组,一个字符的捕获组,可以在负字符集中的反向引用中使用?
在反向引用中引用一个字符,例如第一个字符。
将反向引用称为一组字符而不是字符串......以包含在否定集中。
使用环视断言。唉,我们向后看,向前看,但不看at。
也许这对于正则表达式来说太难了?
您可以使用以下内容:
^
\s*
( setting \s* = \s* )
(
( ['"]? )
[^\s#'"]*
\3
)
( \s* \# \s* .* )?
这三个部分分别在
$1
、$2
和$4
。