【问题标题】:Regex Matching Error正则表达式匹配错误
【发布时间】:2009-08-12 21:15:29
【问题描述】:

我是 Python 新手(我也没有接受过任何编程培训),所以在我提问时请记住这一点。

我正在尝试搜索检索到的网页并使用指定模式查找所有链接。我已在其他脚本中成功完成此操作,但我收到一条错误消息,提示

raise error, v # invalid expression

sre_constants.error: 多次重复

我不得不承认我不知道为什么,但我还是 Python 和正则表达式的新手。但是,即使我不使用模式并使用特定链接(只是为了测试匹配),我也不相信我会返回任何匹配项(当我打印 match.group(0) 时不会将任何内容发送到窗口。链接我测试的在下面被注释掉了。

有什么想法吗?通过示例学习通常对我来说更容易,但非常感谢您提供的任何建议!

布洛克

import urllib2
from BeautifulSoup import BeautifulSoup
import re

url = "http://forums.epicgames.com/archive/index.php?f-356-p-164.html"
page = urllib2.urlopen(url).read()
soup = BeautifulSoup(page)

pattern = r'<a href="http://forums.epicgames.com/archive/index.php?t-([0-9]+).html">(.?+)</a> <i>((.?+) replies)'
#pattern = r'href="http://forums.epicgames.com/archive/index.php?t-622233.html">Gears of War 2: Horde Gameplay</a> <i>(20 replies)'

for match in re.finditer(pattern, page, re.S):
    print match(0)

【问题讨论】:

    标签: python regex


    【解决方案1】:

    这意味着你的正则表达式有错误。

    (.?+)</a> <i>((.?+)
    

    ?+ 是什么意思?两个都 ?和 + 是元字符,彼此相邻是没有意义的。也许你忘了逃避'?什么的。

    【讨论】:

    • 它们以其他顺序有意义。 +?是 + 的非贪婪匹配形式。
    【解决方案2】:

    您需要转义文字“?”以及您尝试匹配的文字 '(' 和 ')'。

    另外,我认为您正在寻找 '+?' 提供的非贪婪匹配,而不是 '?+'。

    More documentation here.

    对于你的情况,试试这个:

    pattern = r'<a href="http://forums.epicgames.com/archive/index.php\?t-([0-9]+).html"> (.+?)</a> <i>\((.+?) replies\)'
    

    【讨论】:

    • 我更改了模式并再次运行脚本,但没有找到匹配项,至少当我尝试遍历匹配项并打印它们时,窗口中没有打印任何内容。有什么想法吗?
    • 手动查看文件内容。当我查看它时,我在任何地方都看不到字符串“回复”。所以正则表达式不会找到任何匹配项。
    • 模式 = r'forums.epicgames.com/archive/index.php\?t-([0-9]+).html">(.+?)( \ (([0-9]+?) 回复\))?'可能更近?
    • 我尝试了你的新模式,但我没有得到的是它没有返回任何匹配项。我什至缩短了模式并尝试了这段代码,当我尝试打印 match.group(0) 时,没有(我认为)被发送到控制台。有任何想法吗? pattern = r'(.+?)' 用于匹配.finditer(pattern, page, re.S): print match(0)
    【解决方案3】:

    正如您所发现的,正确解析任意 HTML 并不容易。这就是像 Beautiful Soup 这样的包装所做的。请注意,您在脚本中调用它,但没有使用结果。请参阅其文档here,了解如何让您的任务更轻松的示例!

    【讨论】:

    • 我已经尝试过文档。由于我是 Python 新手,甚至是 HTML 新手,我很难“轻松”找到我需要它做的事情,尽管我毫不怀疑它可以做我需要的事情。
    【解决方案4】:
    import urllib2
    import re
    from BeautifulSoup import BeautifulSoup
    
    url = "http://forums.epicgames.com/archive/index.php?f-356-p-164.html"
    page = urllib2.urlopen(url).read()
    soup = BeautifulSoup(page)
    
    # Get all the links
    links = [str(match) for match in soup('a')]
    
    s = r'<a href="http://forums.epicgames.com/archive/index.php\?t-\d+.html">(.+?)</a>' 
    r = re.compile(s)
    for link in links:
        m = r.match(link)
        if m:
            print m.groups(1)[0]
    

    【讨论】:

    • 是否可以过滤我想要的链接...正如您在我尝试做正则表达式时看到的那样,我想要一组链接。此外,我知道我很幸运,我希望能得到链接文本。简而言之,是否可以过滤返回的链接并获取链接文本?
    • 几件事:什么是“链接文本”? 之间的东西?还是href值?还是打开和关闭之后的一些东西?还是别的什么?¶ 以下是我没有得到的信息:您指向的页面forums.epicgames.com/archive/index.php?f-356-p-164.html 在 HTML 源代码中甚至没有一个“回复”实例。你确定你正在寻找那个吗?为什么你接受了一个无法匹配数据中任何链接的正则表达式作为答案?¶
    • 新的堆栈溢出,没有意识到这意味着我已经完成了,对不起。通过链接文本,我只想要源代码中链接之后的文本( 之前的文本。由于我是 Python 和网络抓取的新手,所以我开始很慢并尝试尽可能多地学习。但我要做的就是从该存档(每个页面)中获取链接,点击每个链接(讨论),并获取该讨论的所有帖子。我需要将数据解析为“数据集”,它可以是一个列表,但简单地说,我想抓取档案并收集每个消息的所有标题和帖子。
    • 将解决方案标记为“唯一”通常意味着您对它感到满意,响应者不会期望通过进一步的努力获得任何荣誉。此外,如果您选择了其中一种解决方案但它实际上不起作用,那么响应者应该怎么做?新版本的代码转到您引用的网页,抓取所有链接,然后打印开始和结束锚标记之间的所有文本。我想这就是你想要的。
    【解决方案5】:

    扩展其他人写的内容:

    .?表示“任何字符的一个或零”

    .+ 表示“任意字符的一个或多个”

    如您所见,将两者结合起来毫无意义;它们是不同且矛盾的“重复”字符。因此,您关于“多次重复”的错误是因为您在正则表达式中组合了这两个“重复”字符。要修复它,只需确定您实际要使用的那个,然后删除另一个。

    【讨论】:

    • 除了 .+?是一个或多个字符的非贪婪匹配。这就是他所追求的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-30
    • 2011-05-01
    相关资源
    最近更新 更多