Perl和元字符中的斜杠和散列

时间:2011-02-15 14:01:37

标签: regex perl slash

感谢大家以前的帮助!我在Perl中有关于RegExp的查询

我的问题是......

我知道,匹配时你可以写m //或//或##(如果你使用它,必须包括m或s)。是什么让我感到困惑是一本关于逃避角色的书籍例子。我相信大多数人都逃脱了很多角色,作为一个可靠的计划工作方式而不会错过元字符,例如:\ @当想要在电子邮件地址中匹配@ say。

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

$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"); }或类似的东西

那你从什么不使用哈希或斜线逃脱了什么?我知道你必须逃脱元字符以匹配它们但我很困惑。

6 个答案:

答案 0 :(得分:8)

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

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

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

答案 1 :(得分:3)

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

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

答案 2 :(得分:3)

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

替代表达式的格式为:

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

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

答案 3 :(得分:3)

问题本身已经在几个答案中得到了适当的回答。 但是你可以在perldoc perlreperldoc perlrequickperldoc perlretut中找到你一直想知道的有关Perl正则表达式的所有内容,但可能会或可能不会害怕提出。我建议你仔细阅读。

答案 4 :(得分:2)

如果您不使用斜杠,建议的做法是使用花括号和/ x修饰符。

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

逃避非字母数字也是一种标准,即使它们不是元字符。请参阅perldoc -f quotemeta

答案 5 :(得分: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