在 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 中使用正则表达式识别和捕获文本时遇到问题的主要内容,如果未能解决你的问题,请参考以下文章

python中的正则表达式中的 ""

15.python正则匹配 元字符转义重复或捕获分组断言:零度断言负向零宽断言贪婪非贪婪引擎选项

如何通过正则表达式识别文本中的段落?

正则表达式中的或与

用于捕获组的正则表达式无法识别

识别 Bash 脚本中文件扩展名的正则表达式模式不准确以捕获压缩文件