2

我正在使用 Python 中的正则表达式从文本中提取部分 URL。我正在寻找的 URL 来自一组有限的模式,所以感觉我应该能够在正则表达式中处理它们。我要提取的是文件名的第一部分(以下所有示例中的“some.file.name”),其中可以包括点、字母和数字。

这些是 URL 可以采用的形式:

http://www.example.com/some.file.name.html
http://www.example.com/some.file.name_foo.html
http://www.example.com/some.file.name(123).html
http://www.example.com/some.file.name_foo(123).html
http://www.example.com/some.file.name
http://www.example.com/some.file.name_foo
http://www.example.com/some.file.name(123)
http://www.example.com/some.file.name_foo(123)

我想我对这个正则表达式非常满意:

http://www\.example\.com/([a-zA-Z0-9\.]+)(_[a-z]+)?(\(\d+\))?(\.html)?

但是当 URL 类似于列表中的第一个时,它会在匹配项中包含“.html”。有什么方法可以阻止这种情况,还是正则表达式的基本限制?

我很高兴删除代码中的扩展名,因为它始终是相同的,并且永远不会作为文件名的一部分有效,但将其作为正则表达式匹配的一部分会更干净。

编辑:

我要强调的是,这些 URL 是在正文中。我无法保证它们之前或之后是否有字符,或者这些字符可能是什么。我认为可以安全地假设它们不会是数字、字母、下划线或圆点。

4

3 回答 3

2

默认情况下,正则表达式是贪婪匹配的。

试试这个正则表达式:

^http://www\.example\.com/([a-zA-Z0-9\.]+?)(_[a-z]+)?(\(\d+\))?(\.html)?$

请注意,在第一部分中添加的额外?内容未捕获。.html它使第一组捕获尽可能少地匹配,而不是尽可能多地匹配。如果没有?.html将被包含在第一组中,因为其他组是可选的,并且贪婪匹配尝试尽可能“早”匹配。

PS 另请注意,我使用^$始终匹配整行来锚定正则表达式。

于 2012-05-31T07:25:00.880 回答
0

您可以将 .html 扩展名指定为非捕获组:

http://www\.example\.com/([a-zA-Z0-9\.]+)(_[a-z]+)?(\(\d+\))?(?=(\.html)?)
于 2012-05-31T07:24:49.483 回答
0

在我看来,您不关心文件扩展名。您只想提取文件名。

试试这个:

http://www\.example\.com/([\w]+.[\w]+.[\w()]+)

在 PHP 中,我使用了 preg_match_all($regex, $str, $matches),它返回了类似这样的内容。

Array
(
    [0] => Array
        (
            [0] => http://www.example.com/some.file.name
            [1] => http://www.example.com/some.file.name_foo
            [2] => http://www.example.com/some.file.name(123)
            [3] => http://www.example.com/some.file.name_foo(123)
            [4] => http://www.example.com/some.file.name
            [5] => http://www.example.com/some.file.name_foo
            [6] => http://www.example.com/some.file.name(123)
            [7] => http://www.example.com/some.file.name_foo(123)
        )

    [1] => Array
        (
            [0] => some.file.name
            [1] => some.file.name_foo
            [2] => some.file.name(123)
            [3] => some.file.name_foo(123)
            [4] => some.file.name
            [5] => some.file.name_foo
            [6] => some.file.name(123)
            [7] => some.file.name_foo(123)
        )

)

希望能帮助到你!

于 2012-05-31T09:32:02.810 回答