1

我有一个 Perl 替换,它将超链接转换为小写:

's/(?<=<a href=")([^"]+)(?=")/\L$1/g'

我希望替换忽略以散列开头的任何链接,例如我希望它将路径更改<a href="FooBar/Foo.bar">Foo Bar</a>为小写但如果遇到<a href="#Bar">Bar</a>.

嵌套前瞻以指示它跳过这些链接对我来说无法正常工作。这是我写的单行:

perl -pi -e 's/(?<=<a href=" (?! (?<=<a href="#) ) )([^"]+)(?=")/\L$1/g' *;

任何人都可以向我暗示我在这个替换中出了什么问题吗?它执行得很好,但没有做任何事情。

4

2 回答 2

1

据我所知,如果您添加链接中的第一个字符可能不是哈希#或双引号的条件,您的初始正则表达式将可以正常工作,例如[^#"]

s/(?<=<a href=")([^#"][^"]+)(?=")/\L$1/gi;

如果您有不以哈希开头的链接,例如<a href="FooBar/Foo.bar#BarBar">Foo Bar</a>,它会变得稍微复杂一些:

s{(?<=<a href=")([^#"]+)(#[^"]+)*(?=")}{ lc($1) . ($2 // "") }gei;

我们现在必须评估替换,否则当可选的锚引用不存在时,我们会收到未定义的变量警告。

于 2011-10-10T14:17:41.400 回答
1

从我所见,你不需要环顾四周

use 5.010;
...

s/<a \s+ href \s* = \s* "\K([^#"][^"]*)"/\L$1"/gx;

\K意思是“保留”一切。它相当于一个可变长度的后视。

perlre

由于各种原因,\K 可能比等效(?<=...)构造更有效,并且在您想要有效地删除字符串中其他内容之后的某些内容的情况下,它特别有用。

于 2011-10-10T14:39:54.943 回答