在 Python 中使用正则表达式识别和捕获文本时遇到问题
Posted
技术标签:
【中文标题】在 Python 中使用正则表达式识别和捕获文本时遇到问题【英文标题】:Trouble identifying & capturing text with regular expressions in Python 【发布时间】:2020-03-08 20:14:13 【问题描述】:我在 *** 和谷歌上环顾四周,但找不到我正在寻找的具体答案。对于正则表达式,我假设是因为它非常具体,而且我不确定我弄错了什么。
我试图在一个长文本字符串中捕获 7 组字符串。我可以捕获 6,但是我无法调整正则表达式来捕获第 7 个字符串。
我试图在下面的文本中捕捉到 7 个组:perks、currency、campaign、tabs、pore、urls、locale
text = 'gon.urls=stringstuffhere;gon.pageview=morstrings;gon.porestringstuffhere;
gon.capture=allyourstrings;
gon.perks=stringshere;gon.base=stringsbelongtous;gon.campaign=evenmorestrings;gon.haha=somanystrings;
gon.tabs=[morestringsmorestringsmore strings];
gon.main=mainstringsturnon;gon.currency=strings;
gon.locale="en";gon.default_later="somestrings"'
关于正在搜索的字符串的一些说明
我尝试搜索的每个部分都以“gon.title”开头 上述文本的所有格式在“gon.title”、“=”和括号/大括号(或不)方面都是准确的。实际文本的唯一区别是这些括号/括号内的文本。 我捕获的文本大小不一,包括各种文本,包括字母数字、空白和非空白字符 我正在搜索的大部分部分都夹在我未捕获的其他“gon”字符串之间,但紧随另一个捕获组之后的“语言环境”组除外。 我正在搜索的字符串之一 (gon.tabs) 以方括号“[”开头,其他字符串(除了语言环境)以 开头 每个字符串在每个“gon”部分后都有一个分号,开始下一个“gon”组 上述文本的所有格式在“gon.title”、“=”和括号/大括号(或不)方面都是准确的。实际文本的唯一区别是这些括号/括号内的文本。 'gon.locale' 是丢失的部分到目前为止,我的方法是找到具有 'gon.title、'=' 符号和可能的 '[' 或 '' 的部分,然后捕获我想要的文本like,并可能以 '' 或 ']' 结尾,后跟 ';'。
这是我目前用来捕获数据的模式:
result= re.findall('gon.(perks|currency|campaign|tabs|pore|urls|locale)=\[?\?(.*?)\"?\?\]?;', text)
这会捕获所有 7 个字符串,但是由于正在捕获的文本中存在分号,因此它不会捕获其中一个字符串的 all。 (文本可以有未知数量的分号)。
输出是这样的:
[('urls',
'stringstuffhere'),
('pore',
'stringstu')...] #rest of the groups are captured correctly, but off from a semi colon in the string
我尝试将模式调整为:
result= re.findall('gon.(perks|currency_exchange|campaign|tabs|trust_passport|urls|locale)=\[?\?(.*?)\"?\?\]?;gon', text)
添加下一个“组”文本的“gon”。这有助于捕获我丢失的所有部分,但是,它不找到/捕获“gon.locale”字符串。
输出是这样的:
[('urls',
'stringstuffhere'),
('pore',
'stringstuffhere'),
('tabs',
'morestringsmorestringsmore strings'),
('campaign',
'evenmorestrings'),
('perks',
'stringshere'),
('currency',
'strings'),
('pore',
'stringstuffhere')] #locale group missing
我尝试了各种不同的选项调整,包括使用原始字符串。但要么我错过了一个字符串组中的一些数据并捕获了第 7 个字符串,或者我错过了一个字符串组,但捕获了我找到的组中的所有数据。
所需的结果与上面的最新示例类似,但缺少“区域设置”组。我不知道为什么在模式的末尾添加“g”或“gon”会使那部分脱落。
任何帮助将不胜感激! 如果我能澄清上面的解释,请告诉我。
**** 进行了编辑。使用 https://regex101.com/ 工具构建时。我看到最后一个“语言环境”组直接在我正在捕获的另一个组之后。因此,在搜索字符串时,将“g”添加到模式的末尾有助于捕获我丢失的所有字符串,但“指针”不再包含下一组的“g”,而是从下一个字母“o”。
我发现了两个可行的选项,为“locale”组添加另一个以“on”开头的模式,或者使用与下一个“gon”字符串匹配的正向前瞻,而不使其成为匹配的一部分。下面有两种模式。
r'(?<=gon\.)(perks|currency|campaign|tabs|pore|urls|locale)\[??\"?(.+?)\"??\]?;(?=g)|on\.(locale)=(\"\w+\");', html)
r'gon.(perks|currency|campaign|tabs|pore|urls|locale)=\[?\?(.*?\"?)\?\]?;(?=gon)'
【问题讨论】:
那个字符串是从哪里来的?它肯定代表某种数据格式,对吧?另外,我发现在处理正则表达式时非常有用的工具是regex101.com。 【参考方案1】:也许,
gon\.(perks|currency|campaign|tabs|trust_passport|urls|locale)=\[??"?(.*?)"??\]?;|gon\.pore([^]+)
或者,
gon\.(perks|currency|campaign|tabs|trust_passport|urls|locale|pore)=?\[??"?(.*?)"??\]?;
在这里工作就好了。
Demo
测试 1
import re
string = '''
gon.urls=stringstuffhere;gon.pageview=morstrings;gon.porestringstuffhere;
gon.capture=allyourstrings;
gon.perks=stringshere;gon.base=stringsbelongtous;gon.campaign=evenmorestrings;gon.haha=somanystrings;
gon.tabs=[morestringsmorestringsmore strings];
gon.main=mainstringsturnon;gon.currency=strings;gon.bub=someonesetusup;
gon.locale="en";gon.default_later="somestrings
'''
expression = r'(?m)gon\.(perks|currency|campaign|tabs|trust_passport|urls|locale)=\[??"?(.*?)"??\]?;|gon\.pore([^]+)'
print(re.findall(expression, string))
输出 1
[('urls', 'stringstuffhere', ''), ('', '', 'stringstuffhere'), ('perks', 'stringshere', ''), ('campaign', 'evenmorestrings', ''), ('tabs', 'morestringsmorestringsmore strings', ''), ('currency', 'strings', ''), ('locale', 'en', '')]
测试 2
import re
string = '''
gon.urls=stringstuffhere;gon.pageview=morstrings;gon.porestringstuffhere;
gon.capture=allyourstrings;
gon.perks=stringshere;gon.base=stringsbelongtous;gon.campaign=evenmorestrings;gon.haha=somanystrings;
gon.tabs=[morestringsmorestringsmore strings];
gon.main=mainstringsturnon;gon.currency=strings;gon.bub=someonesetusup;
gon.locale="en";gon.default_later="somestrings
'''
expression = r'(?m)gon\.(perks|currency|campaign|tabs|trust_passport|urls|locale|pore)=?\[??"?(.*?)"??\]?;'
print(re.findall(expression, string))
输出 2
[('urls', 'stringstuffhere'), ('pore', 'stringstuffhere'), ('perks', 'stringshere'), ('campaign', 'evenmorestrings'), ('tabs', 'morestringsmorestringsmore strings'), ('currency', 'strings'), ('locale', 'en')]
如果您希望简化/修改/探索表达式,在regex101.com 的右上角面板中已对此进行了说明。如果您愿意,您还可以在this link 中观看它如何与一些示例输入匹配。
正则表达式电路
jex.im 可视化正则表达式:
【讨论】:
感谢您的示例。不幸的是,这两个例子和我原来的模式在同一个地方“卡住”了。它停止工作的模式是这样的文本:'“text here”。\\n 更多需要捕获的文本..'' 这是原始文本,捕获的是这部分: ' '在这打字”。 \\n '。谢谢你的链接!我会尝试使用这些资源,非常感谢! 'gon\.(perks|currency|campaign|tabs|pore|urls)=[??\"?(.+?)\"??]?;+?g| on\.(locale)=(\"\w+\");'似乎工作!但是,我有很多零长度匹配。我需要尝试调整一下以整理一下。谢谢!通过您的一项资源,我看到“语言环境”组实际上位于另一个捕获组之后。因为“g”在第一个模式中,它永远不会捕获“locale”模式的 g,所以我切换到“on”,它捕获了组。 我在没有引入零长度匹配的情况下找到了解决方案。这是我在原始问题中的第二个示例,但将“gon”放在末尾作为前瞻断言。 'gon.(perks|currency_exchange|campaign|tabs|trust_passport|urls|locale)=[?\?(.*?)\"?\?]?;(?=gon)'。谢谢你的帮助!!以上是关于在 Python 中使用正则表达式识别和捕获文本时遇到问题的主要内容,如果未能解决你的问题,请参考以下文章