如何安全地提取 Emacs 正则表达式中的 URL



我使用正则表达式可靠地从HTTP标头中提取URL时遇到了很大的问题。标题交替到达和不带有 ^M 字符,这似乎与空格类不匹配。目前我迄今为止管理的最好的是:

(re-search-forward "^x-url: .*/\{2,3\}\(.*\)" nil t)
但是,当然,如果

存在^M,这也可以选择我并不真正需要的URL参数。举一个我调试的例子:

x-url: http://wiki/mediawiki/index.php?title=Vsmux&action=edit&redlink=1
x-url: http://wiki/mediawiki/index.php?title=Vsmux&action=edit&redlink=1^M

在这两种情况下,我真正想要的只是结果:

wiki/mediawiki/index.php

这看起来很可怕,但我不对它的外观负责——发明这个愚蠢标准的人是......但这应该非常紧密地遵循标准(旧版本,其中不包括 Unicode 字符及其翻译):

"^x-url:\s-*\(\w\|\+\|-\)+://\(\w\|\-\)+\(\.\w+\)?\(\/\(%[0-9a-fA-F]\{2\}\|[~\.A-Za-z_+-]*\)*\)*"

除非某些"有用"程序已经将百分比编码的URI组件转换为其原始的非编码形式。

此外,对于 URL 的各个部分可能有多长有一些技术限制,我不会尝试实现它......

此外,它假定从不使用身份验证方案(如基本身份验证中的方案)。否则,在没有正则表达式的情况下做到这一点会容易得多。

像这样的东西怎么样(这假设所有网址中都有"://"):

(re-search-forward "^x-url: [^:]*://\([^?rn]+\).*?$")

为了完整起见,我可能应该根据与@wvxvw关于使用正确解析器的讨论添加另一个我尝试过的解决方案。这呈现为 elisp 代码,看起来有点像这样:

(save-excursion
  (let* ((url-string (url-get-url-at-point (re-search-forward "^x-url: ")))
         (url (url-generic-parse-url url-string))
         (arg-split (string-match-p "?" (url-filename url))))
    (format "%s%s" (url-host url)
        (if arg-split
            (substring (url-filename url) 0 arg-split)
          (url-filename url)))))

最新更新