2

此代码片段来自《精通正则表达式》一书。我无法理解带有负面回顾的最后一部分(评论 # Not allowed to end with [.,?!])。该表达式将如何[?!,.]http://www.google.com/foo!or中删除http://www.google.com/bar\!

# Turn HTTP URLs into links . . . 
$text =~ s{
   \b
   # Capture the URL to $1 . . . 
   (
      http:// [-a-z0-9]+(\.[-a-z0-9]+)*\.(com|edu|info) \b   # hostname
      (
         / [-a-z0-9_:\@&?=+,.!/~*'%\$]* # Optional path
         (?<![.,?!])    # Path not allowed to end with [.,?!]
      )?
   )
}{<a href="$1">$1</a>}gix;

print $text; # Finally, display the HTML-ized text.
4

2 回答 2

4

它不会。它在表达式的一部分是可选路径被匹配,并且由于没有路径 in http://www.google.com,它不会有任何效果。

于 2014-06-10T11:24:03.570 回答
3

这个想法是,当[-a-z0-9_:@&?=+,.!/~*%\$]+它耗尽所有可能的东西时,它将控制权交给后视。如果后视系统看到这些句子标点字符之一,它会报告失败并将控制权交还给该[-a-z0-9_:\@&?=+,.!/~*%\$]+部分。它后退一个位置,“归还”它消耗的最后一个角色,然后再次将手交给后视。

在 的情况下www.google.com/foo!,lookbehind 现在将查看o,因此它报告成功并且整体匹配成功。

但是,当您尝试匹配www.google.com/bar\!lookbehind 时,永远没有机会查看 bang ( !)。[-a-z0-9_:\@&?=+,.!/~*%\$]+不匹配反斜杠,因为它们在 URL 中是不合法的。它在消耗完 后停止r,这一次后视成功而无需回溯。

编辑:回答评论中的问题:是的,您可以使用以下内容:

\b(https?|ftp|file)://[-A-Z0-9+&@#/%?=~_|$!:,.;]*[A-Z0-9+&@#/%=~_|$]

在后向正则表达式消耗无效字符并将它们备份的地方,这个正则表达式首先不会消耗它们。但并不总是可以这样做。例如,如果您要排除的内容是整个单词而不是单个字符怎么办?那会变得非常丑陋,非常快。我的意思是,看看你必须输入的所有字符,只是为了完成这个最基本的匹配任务。

于 2014-06-10T12:42:39.027 回答