【问题标题】:Regex Expression wrong正则表达式错误
【发布时间】:2019-09-20 16:42:33
【问题描述】:

我正在尝试从以下短语中提取国家(此处为印度尼西亚):

<small class="text-muted">
                            <span class="hidden-xs">Football / </span>Indonesia / 
                            <span class="hidden-xs xh-highlight">Kick off: </span>11 Sep 2019, 11:30                            </small>

目前,我只是使用以下命令来提取文本:

.xpath('.//small[@class="text-muted"]/text()').extract()

仅提取印度尼西亚的正确正则表达式命令是什么?

【问题讨论】:

  • 这似乎是一个XPath问题,与正则表达式无关。

标签: regex xpath scrapy web-crawler


【解决方案1】:

您可以使用这个 XPath-1.0 表达式:

//small[@class="text-muted"]/span[@class="hidden-xs"]/following-sibling::text()

结果为@​​987654323@。
如果你想摆脱斜线,你有几种可能:

  1. 从表达式中删除所有斜杠:

    normalize-space(translate(//small[@class="text-muted"]/span[@class="hidden-xs"]/following-sibling::text(),"/",""))
    
  2. 使用substring-before()获取斜杠前的字符串:

    normalize-space(substring-before(//small[@class="text-muted"]/span[@class="hidden-xs"]/following-sibling::text(),"/"))
    
  3. 使用substring-before()获取第一个空格前的字符串:

    normalize-space(substring-before(//small[@class="text-muted"]/span[@class="hidden-xs"]/following-sibling::text()," "))
    

还有其他 XPath 表达式也可以。选择最适合您情况的一种。仅当您指定到当前节点的相对路径时,// 之前的前导点才是必需的。在上面的表达式中,我确实假设查找是全局的。

当然,这些 XPath 表达式必须用

包围
.xpath('...').extract()

【讨论】:

  • 嘿 zx485 - 感谢您的回答。这是工作。开球后我必须做什么才能提取所有内容?我想提取“2019 年 9 月 11 日,11:30”
  • 一种方法是将第二个@class 值从span[@class="hidden-xs"] 调整为span[@class="hidden-xs xh-highlight"](或span[contains(@class,"xh-highlight")])。
  • 我正在使用以下命令:post.xpath('normalize-space(.//small[@class="text-muted"]/span[@class="hidden-xs xh-highlight"]/following-sibling::text())').extract() 但它不起作用。我删除了 subtring-before 函数,因为这里不需要它,是吗?
  • 我测试了你的表达方式,对我来说它确实有效。因此,不幸的是,我无法重现您的错误。我 c/p'ed 你的表达式,其结果是11 Sep 2019, 11:30。我还检查了我的第二个变体,它也确实有效。因为这似乎是一个新问题的出现,我建议你用一个好的minimal reproducible example 提出一个新问题来解决这个问题。
  • 好的 - 上述代码中的“hidden-xs xh-highlight”类是错误的。也是“hidden-xs”类。我使用以下命令获取数据(也许不是最有效的答案):kickoff = post.xpath('.//small[@class="text-muted"]/span[@class="hidden-xs"]/following-sibling::text()').re('([^/]+$)') kickoff = [x.strip(' ') for x in kickoff] kickoff = [kickoff[1]]
【解决方案2】:

也许,从bs4 导入BeautifulSoup,我们可以提取国家,如果可以的话:

from bs4 import BeautifulSoup
import re

string="""
<small class="text-muted">
                            <span class="hidden-xs">Football / </span>Indonesia / 
                            <span class="hidden-xs xh-highlight">Kick off: </span>11 Sep 2019, 11:30                            </small>
A

"""

soup = BeautifulSoup(string, 'html.parser').find_all('small')[0].text

print(re.findall(r'[^/]+/\s*([^/]+?)\s*/', soup)[0])

输出

Indonesia

【讨论】:

    【解决方案3】:

    问题是,您对输入了解多少?您显然不知道它包含“印度尼西亚”,但输入的所有其他部分是否完全固定?例如,您要查找的文本是否总是紧跟在内容为 Football / 的 span 元素之后?

    如果是这样,那么你可以这样做

    //small[@class="text-muted"]/span[. = Football / ']/following-sibling::text()[1]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-11-19
      • 1970-01-01
      • 2013-11-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多