python 正则匹配,findall 或 search 不返回值

0 投票
3 回答
1869 浏览
提问于 2025-04-17 09:44

我正在尝试从一个字符串中找到一个标记并返回它。我在其他字符串上使用这个方法时效果很好,但这个字符串似乎没有返回任何结果。无论是用findall还是search都不行。

pattern= re.compile(r'<input class="token"  value="(.+?)" name="csrftoken_reply">')
    matches = pattern.findall(htmlstring)
    for match in matches:
        print match

每个响应字符串中只有一个值,但我没有得到“打印匹配”的结果。

我也尝试过使用re.search,但结果还是一样,返回的是一个NoneType对象……

更多信息:

这是我正在解析的HTML的一部分:

<form id="threadReplyForm" class="clearfix" method="post" action="/go/messages/private/threadID=0551796">
<input class="csrftoken" type="hidden" value="a7b161b7" name="csrftoken_reply">
<input type="hidden" value="reply" name="action">
<div class="editorWrapper">
<div id="premiumSmiliesNotAllowed" class="warning" style="display: none;">
<div id="editor_13" class="clearfix editor" mode="full">
<ul id="editorToolbar_13" class="editorToolbar clearfix">
<textarea id="messageInput" class="autogrow" cols="20" rows="8" name="message"></textarea>
<div id="previewDiv" class="previewArea" style="display: none;"></div>
</div>
<script>
</div>
<script>
<span class="loadingIndicator right loadingIndicatorMessage">
<p class="clearfix">
</form>

我用这个来解析:

pattern= re.compile(r'<input class="csrftoken" type="hidden" value="(.+?)" name="csrftoken_reply">')
    matches = pattern.findall(str(response.read()))
    for match in matches:
        print match

我想要的输出是a7b161b7

3 个回答

0

抱歉,2011年用正则表达式解析HTML简直是疯狂 :) 现在有很多专门为这个任务优化的库,其中最好的就是上面提到的BeautifulSoup和lxml。我能理解你不想用lxml,因为它的依赖项很多,安装起来也很麻烦,但BeautifulSoup只需要一个文件,能让你的代码更加稳定。

总结一下:你是在重复造轮子。

1

你需要给出一个你想要解析的字符串示例,因为对我来说这个是有效的。

import re

htmlstring = """
<input class="token"  value="foo" name="csrftoken_reply">
"""

pattern= re.compile(r'<input class="token"  value="(.+?)" name="csrftoken_reply">')
matches = pattern.findall(htmlstring)
for match in matches:
    print match

除此之外,你有没有考虑过使用一些专门为这种情况设计的库?使用正则表达式解析HTML可能会比较脆弱。Beautiful Soup似乎是一个很受欢迎的工具。

更新

你有一个错误的类值,还有一个多余的空格,并且你忘记了 'input type="hidden"'。这里有一个更接近的例子,不过我还是不建议使用正则表达式:

r'<input class="csrftoken" type="hidden" value="(.+?)" name="csrftoken_reply">'

这个也可以用(我假设只有一个 'csrftoken_reply' 元素):

r'value="(.+?)" name="csrftoken_reply">'

这两种方法都能帮你获取到想要的值。

0

我不是Python专家,也不推荐用正则表达式来解析HTML,但这样做可能可以获取无序的属性-值数据。只需要放入一些必要的键值对来确定标签的类型。并不需要全部的键值对,也不需要按特定顺序。

修饰符:扩展、单行字符串、全局。
值捕获组是$5。

编辑
我把(?= (?:".*?"|\'.*?\'|[^>]*?)+改成了(?= (?:[^>"\']|(?>".*?"|\'.*?\'))*?,因为这种形式的懒惰量词会被迫超出标记边界来满足前瞻条件。新的子表达式可以处理attr="so< m >e"中嵌入的标记,而不会出现超出的问题。

<input 
  (?=\s) 
  (?= (?:[^>"\']|(?>".*?"|\'.*?\'))*? (?<=\s) class \s*=\s* ([\'"]) \s* csrftoken \s*\1 )
  (?= (?:[^>"\']|(?>".*?"|\'.*?\'))*? (?<=\s) name  \s*=\s* ([\'"]) \s* csrftoken_reply \s*\2 )
  (?= (?:[^>"\']|(?>".*?"|\'.*?\'))*? (?<=\s) type  \s*=\s* ([\'"]) \s* hidden \s*\3 )
  (?= (?:[^>"\']|(?>".*?"|\'.*?\'))*? (?<=\s) value \s*=\s* ([\'"]) \s* (.*?)  \s*\4 )
  \s+ (?:".*?"|\'.*?\'|[^>]*?)+ (?<!/)
>

所有的注意事项都适用,可能会隐藏在嵌入的代码中,可能是注释等等...
对此需要额外的正则逻辑。

撰写回答