1

感谢大家之前的帮助!我对 Perl 中的 RegExp 有疑问

我的问题是..

我知道,匹配时你可以写 m// 或 // 或 ##(如果你使用这个,必须包括 m 或 s)。让我感到困惑的是一本关于我所拥有的转义字符的书籍示例。我相信大多数人都会转义很多字符,作为程序工作的一种可靠方式,不会丢失元字符,例如:\@ 当在电子邮件地址中寻找匹配 @ 时。

这是我的问题,我知道这个脚本的作用:

$date= "15/12/99"
$date=~ s#(\d+)/(\d+)/(\d+)#$1/$2/$3#; << why are no forward slashes escaped??
print($date);

然而,我后面的例子显示它被重写为(我也理解并且他们被逃脱了)

$date =~ s/()(\d+)\/(\d+)\/(d+)/$2\/$1\/$3; <<<<which is escaping the forward slashes.

我知道斜线或散列是程序员的偏好和它们的用途。我不明白的是为什么第二个例子,逃脱了斜线,但第一个没有 - 我已经尝试过,它们都是双向的。没有用散列转义斜线?更令人困惑的是,查看我之前也有的另一本书示例,再次使用哈希,它们也转义了 @ 符号。

if ($address =~ m#\@#) { print("That's an email address"); }或类似的东西

那么,您从不使用哈希或斜杠的情况中逃脱了什么?我知道您必须转义元字符才能匹配它们,但我很困惑。

4

6 回答 6

8

当您构建一个正则表达式时,您将一个字符定义为您的正则表达式的分隔符,即做//##
如果您需要在您的正则表达式中使用该字符,您需要将其转义,以便正则表达式引擎不会将其视为正则表达式的结尾。

如果您在正斜杠之间构建正则表达式/,则需要转义正则表达式中包含的正斜杠,因此在第二个示例中进行转义。

当然,同样的规则适用于您用作正则表达式分隔符的任何字符,而不仅仅是正斜杠。

于 2011-02-15T14:07:37.160 回答
4

正斜杠本身不是元字符 - 只有在第二个示例中使用它们作为表达式分隔符才使它们“特殊”。

替换表达式的格式为:

s<expression separator char><expression to look for><expression separator char><expression to replace with><expression separator char>

在第一个示例中,使用哈希作为 =~ 之后的第一个字符,使该字符成为表达式分隔符,因此正斜杠并不特殊,不需要任何转义。在第二个示例中,表达式分隔符确实是正斜杠,因此必须在表达式本身内对其进行转义。

于 2011-02-15T14:09:23.100 回答
3

正则表达式匹配运算符允许将自定义非空白字符定义为分隔符。

在您的第一个示例中,“#”用作分隔符。所以在这个正则表达式中你不需要转义'/',因为它没有特殊含义。在第二个正则表达式中,分隔符 char 没有改变。所以使用默认的'/'。现在您必须转义模式中的所有“/”。否则解析器会感到困惑。:)

于 2011-02-15T14:08:20.820 回答
3

这个问题本身已经在几个答案中得到了正确的回答。但是你一直想知道的关于 Perl 正则表达式的一切,但可能会或可能不会害怕问,都可以在perldoc perlreperldoc perlrequickperldoc perlretut中找到。我建议你通读它们。

于 2011-02-15T14:15:22.347 回答
2

如果您不使用斜线,推荐的做法是使用花括号和 /x 修饰符。

$date=~ s{ (\d+) \/ (\d+) \/ (\d+) }{$1/$2/$3}x;

转义非字母数字也是一种标准,即使它们不是元字符。见perldoc -f quotemeta

于 2011-02-15T14:30:11.493 回答
0

关于使用 s 修饰符转义正斜杠的问题还有另一个深度。在我的示例中,捕获成为问题。

$image_name =~ s/((http:\/\/.+\/)\/)/$2/g;

为此,必须捕获添加第二个正斜杠的错字。此外,尝试仅使用两个斜杠也行不通。第一个斜线必须由多个字符引导。将“ http://world.com/Photos//space_shots/out_of_this_world.jpg

更改 为:“ http://world.com/Photos/space_shots/out_of_this_world.jpg

于 2013-10-28T10:11:00.570 回答