Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/342.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 连字符'-';为BeautifulSoup使用正则表达式时产生问题_Python_Regex_Beautifulsoup - Fatal编程技术网

Python 连字符'-';为BeautifulSoup使用正则表达式时产生问题

Python 连字符'-';为BeautifulSoup使用正则表达式时产生问题,python,regex,beautifulsoup,Python,Regex,Beautifulsoup,我正在学习如何使用Wikepedia文章使用python进行webscrape。通过对表行()使用.get_text()方法,我成功地获得了所需的数据表 我正在清理熊猫的数据,其中一项例行工作就是获取一本书或一部电影的出版日期。因为有很多方法可以实现这一点,例如: (1986) (1986-1989) (1986年至今) 目前,我正在使用下面的代码处理测试语句: # get the first columns of row 19 from the table and get its text t

我正在学习如何使用Wikepedia文章使用python进行webscrape。通过对表行()使用.get_text()方法,我成功地获得了所需的数据表

我正在清理熊猫的数据,其中一项例行工作就是获取一本书或一部电影的出版日期。因为有很多方法可以实现这一点,例如: (1986) (1986-1989) (1986年至今)

目前,我正在使用下面的代码处理测试语句:

# get the first columns of row 19 from the table and get its text
test = data_collector[19].find_all('td')[0]
text = test.get_text()
#create and test the pattern
pattern = re.compile('\(\d\d\d\d\)|\(\d\d\d\d-\d\d\d\d\)|\(\d\d\d\d-[ Ppresent]*\)')
re.findall(pattern, 'This is Agent (1857), the years were (1987-1868), which lasted from (1678- Present)')
我得到了测试句子的预期输出

['(1857)', '(1987-1868)', '(1678- Present)']
然而,当我在维基文章《夏洛克·福尔摩斯历险记(1891-1892)(系列)》(1892)(小说)、亚瑟·柯南·道尔(Arthur Conan Doyle)中的特定文本上测试它时,我能够提取(1892),但无法提取(1891-1892)

即使在我输入这个时,我也可以看到我使用的连字符和文本上的连字符是不同的。我确信这就是问题所在,我希望有人能告诉我这个特殊的符号叫什么,以及我如何用键盘“键入”它


谢谢大家!

我建议增强模式以搜索最常见的连字符,
-
-
-
,并将
当前的
模式从字符类修复为字符序列(以免将发送的
[Ppresent]*
匹配):

看。请注意,
re.I
标志将以不区分大小写的方式使正则表达式匹配

详细信息

  • \(
    -a
  • \d{4}
    -四位数字(
    {4}
    是一个限制量词,它将修改的模式重复四次)
  • (?:[\s–]+(?:\d{4}| present))?
    -可选(因为末尾有一个
    )非捕获(由于
    ?:
    )组匹配
    • [\s–]+
      -1个或多个空格、
      -
      -
      -
    • (?:\d{4}存在)
      -4位数字或
      存在
  • \)
    -a
    字符
如果您计划匹配任何连字符,请使用
[\u002D\u058A\u05BE\u1400\u1806\u2010-\u2015\u2E17\u2E1A\u2E3A\u2E3B\u2E40\u301C\u3030\u30A0\uFE31\uFE32\uFE58\uFE63\uFF0D\s]+
而不是
[\s-]+/code>


或者,要匹配该位置的任何1+非单词字符,可能除了
,使用
[^\w()]+
而不是:
re.compile(r'\(\d{4}(?:[^\w()]+(?:\d{4}present)),re.I)

您确定有连字符而不是em破折号吗?尝试
re.compile(r'\(\d{4}(?:[\s-]+(?:\d{4}存在))?\),re.I)
。请参阅。如果可以使用,可以使用Unicode字符类别
\p{Pd}
来匹配所有破折号-请参阅我同意@Wiktor,字符可能与看起来的不完全相同。另一个解决方案是将“-”替换为“\S”。意思是匹配任何非空白字符
\p{Pd}
都包含很多。但有些看起来不像连字符。然后使用
\u002D\u058A\u05BE\u1400\u1806\u2010-\u2015\u2E17\u2E1A\u2E3A\u2E3B\u2E40\u301C\u3030\u30A0\uFE31\uFE32\uFE58\uFE63\uFF0D
代替连字符/破折号。或者,为了匹配任何非单词字符,可能除了
[^\w()]
=>
re.compile(r'\(\d{4}(?:[^\w()]+(?:\d{4}present)),re.I)
@WiktorStribiż谢谢!你的解决方案完美无瑕。
text = test.get_text()
re.findall(pattern, text)
o/p: ['(1892)']
re.compile(r'\(\d{4}(?:[\s–—-]+(?:\d{4}|present))?\)', re.I)