正则表达式在两个字符串(它们是变量)之间提取
Posted
技术标签:
【中文标题】正则表达式在两个字符串(它们是变量)之间提取【英文标题】:Regex to extract between two strings (which are variables) 【发布时间】:2015-06-21 18:51:36 【问题描述】:我希望使用正则表达式来提取出现在两个字符串之间的文本。我知道如果我每次都想在相同的字符串之间提取(以及无数个问题,例如Regex matching between two strings?),但我想使用发生变化的变量来做到这一点,并且它们本身可能包含正则表达式中的特殊字符。 (我想要任何特殊字符,例如 * 被视为文本)。
例如,如果我有:
text = "<b*>Test</b>"
left_identifier = "<b*>"
right_identifier = "</b>
我想创建将导致以下代码运行的正则表达式代码:
re.findall('<b\*>(.*)<\/b>',text)
是<b\*>(.*)<\/b>
部分,我不知道怎么动态创建。
【问题讨论】:
您可能需要考虑一个非贪婪的量词:(.*?)
这匹配尽可能少的字符。因此,对于像“left_identifierstuffright_identifier left identifiermore stuffright_identifier”这样的字符串,您只会在两个单独的匹配项中找到“stuff”和“more stuff”,而不是“stuffright_identifier” left identifiermore stuff" 在一场比赛中。
谢谢 - 好地方 - 你是对的 - 我的意思是非贪婪量词!
请注意使用正则表达式解析 html is not recommended。您应该使用 HTML 解析器(无论 Python 中的 Nokogiri 是什么),然后从相应的标签中提取文本。
@Phrogz - 示例已简化 - 通常不基于 html 标签进行解析(尽管需要能够处理它们,因为它们会裁剪到我输入的文本中)。 【参考BeautifulSoup是python中等价的html解析器】。
【参考方案1】:
你可以这样做:
import re
pattern_string = re.escape(left_identifier) + "(.*?)" + re.escape(right_identifier)
pattern = re.compile(pattern_string)
转义函数会自动转义特殊字符。例如:
>>> import re
>>> print re.escape("<b*>")
\<b\*\>
【讨论】:
还请注意(.*?)
而不是(.*)
,这是非贪婪捕获。这可能是您想要的。
我尝试使用 "PRIMARY KEY(\n" 作为左侧标识符和 ")" 作为右侧标识符执行上述操作,但对我不起作用。我想从下面获取所有主键: PRIMARY KEY (ROLE_ID) USING INDEX APP_ROLES.SR_PK ENABLE VALIDATE);【参考方案2】:
你需要re.escape
标识符:
>>> regex = re.compile('(.*)'.format(re.escape('<b*>'), re.escape('</b>')))
>>> regex.findall('<b*>Text</b>')
['Text']
【讨论】:
【参考方案3】:正则表达式开始它的生命就像一个字符串,所以left_identifier + text + right_identifier
并在re.compile
中使用它
或者:
re.findall('(.*)'.format(left_identifier, right_identifier), text)
也可以。
如果变量中的字符串包含带有re.escape 的正则表达式元字符,并且您不希望元字符被这样解释,则需要对它们进行转义:
>>> text = "<b*>Test</b>"
>>> left_identifier = "<b*>"
>>> right_identifier = "</b>"
>>> s='(.*?)'.format(*map(re.escape, (left_identifier, right_identifier)))
>>> s
'\\<b\\*\\>(.*?)\\<\\/b\\>'
>>> re.findall(s, text)
['Test']
附带说明,str.partition(var) 是执行此操作的另一种方法:
>>> text.partition(left_identifier)[2].partition(right_identifier)[0]
'Test'
【讨论】:
【参考方案4】:我知道您实际上想要一个正则表达式解决方案,但考虑到we all have taken oath not to,我真的想知道正则表达式是否是正确的工具。在解析 html 字符串时,我总是建议回退到beautifulsoup
>>> import bs4
>>> bs4.BeautifulSoup('<b*>Text</b>').text
u'Text'
【讨论】:
以上是关于正则表达式在两个字符串(它们是变量)之间提取的主要内容,如果未能解决你的问题,请参考以下文章
正则表达式:获取 AWS Redshift 中两个字符串之间的值