【问题标题】:Find a url for a file in html using a regular expression使用正则表达式在 html 中查找文件的 url
【发布时间】:2010-12-18 06:42:45
【问题描述】:

我为自己设定了一个有点雄心勃勃的第一项任务,即学习正则表达式(以及与我要解决的问题相关的任务)。我需要在一个大的 html 字符串中找到任何以 .m4v 结尾的 url 实例。

我的第一次尝试是 jpg 文件

http.*jpg

乍一看这当然是正确的,但当然会返回如下内容:

http://domain.com/page.html" title="Misc"><img src="http://domain.com/image.jpg

理论上与表达式匹配。所以真的,我需要在http.*m4v 中添加一些内容,上面写着“只有 http 和 m4v 之间最近的实例”。有什么想法吗?

【问题讨论】:

  • 什么编程语言...?不幸的是,正则表达式有不同的风格
  • 我正在为 iOS 编写这个代码,它有一个名为 NSRegularExpression 的新类。给定一个字符串和一个表达式,它返回一个与字符串中的表达式匹配的范围数组。确定这是一个与平台无关的谜题吗?
  • 你可以试试这个表达式,它非常基本,所以它应该可以工作 (http|https)://.+\.4mv
  • 这没什么用……这比.*还要贪婪。

标签: objective-c regex


【解决方案1】:

如您所见,如下表达式是贪婪的:

http:.*\.jpg

这意味着它在满足表达式的同时读取尽可能多的输入。

*”运算符使它变得贪婪。有一种定义明确的正则表达式技术可以使这种非贪婪...使用“?” “*”之后的修饰符。

http:.*?\.jpg

现在它将尽可能少地匹配,同时仍然满足表达式(即它将在​​第一次出现“.jpg”时停止搜索。

当然,如果您在 URL 中间有一个 .jpg,例如:

http://mydomain.com/some.jpg-folder/foo.jpg

它不会匹配完整的 URL。

您需要将 URL 的结尾定义为不能被视为 URL 一部分的内容,例如空格或换行符,或者(如果 URL 嵌套在括号中),结束插入语。这不能通过一个小的正则表达式来解决,但是如果它包含在书面语言中,因为 URL 通常是模棱两可的。

举个例子:

At this page, http://mysite.com/puppy.html, there's a cute little puppy dog.

逗号在技术上可以是 URL 的一部分。在寻找书面文本中的 URL 时,您必须处理很多这样的歧义,并且由于歧义而很难没有错误。

编辑 |这是 PHP 中的正则表达式示例,它是一种快速而肮脏的解决方案,仅在需要时才贪婪,并且 尝试 处理英语:

<?php

$str = "Checkout http://www.foo.com/test?items=bat,ball, for info about bats and balls";

preg_match('/https?:\/\/([a-zA-Z0-9][a-zA-Z0-9-]*)(\.[a-zA-Z0-9-]+)*((\/[^\s]*)(?=[\s\.,;!\?]))\b/i', $str, $matches);

var_dump($matches);

它输出:

array(5) {
  [0]=>
  string(38) "http://www.foo.com/test?items=bat,ball"
  [1]=>
  string(3) "www"
  [2]=>
  string(4) ".com"
  [3]=>
  string(20) "/test?items=bat,ball"
  [4]=>
  string(20) "/test?items=bat,ball"
}

解释在cmets中。

【讨论】:

  • 感谢 d11wtq,我觉得没有“征服一切”的解决方案。
  • 这样的事情会做得相当好:/https?:\/\/([a-zA-Z0-9][a-zA-Z0-9-]*)(\.[a-zA-Z0-9-]+)*((\/[^\s]*)(?=[\s\.,;!\?]\s))\b/i(已测试)。这将域部分限制为仅适用于(非 unicode)域的有效字符,后跟可选路径,以空格或标点符号的子集 .,;!? 结尾,仅当标点符号后跟单词边界(例如空格)。
【解决方案2】:

Perl、ruby、php 和 javascript 都应该与这些兼容:

/(http:\/\/(?:(?:(?!\http:\/\/).))+\.jpg)/

网址将存储在匹配的组中。针对"http://a.com/b.jpg-folder/c.jpg @987654321@" 进行了测试,它可以正常工作而不会太贪心。

【讨论】:

  • 这些还是很贪心的。如果 .jpg 或 .m4v 在文本中出现多次,它们将消耗所有内容,直到最后一个 .m4v(只要表达式仍然满足)。
  • 嗯...有趣的困境。我尝试解决它。查看更新的答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-07-24
  • 2016-11-01
  • 2014-01-30
  • 1970-01-01
  • 2012-11-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多