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