您可以使用 Python 正则表达式从偏移量向后搜索吗?
Posted
技术标签:
【中文标题】您可以使用 Python 正则表达式从偏移量向后搜索吗?【英文标题】:Can you search backwards from an offset using a Python regular expression? 【发布时间】:2013-06-16 17:13:08 【问题描述】:给定一个字符串,以及该字符串中的一个字符偏移量,我可以使用 Python 正则表达式向后搜索吗?
我要解决的实际问题是在字符串中的特定偏移处获取匹配的短语,但我必须匹配该偏移之前的第一个实例。
在我的正则表达式只有一个符号长(例如:单词边界)的情况下,我正在使用反转字符串的解决方案。
my_string = "Thanks for looking at my question, ***."
offset = 30
boundary = re.compile(r'\b')
end = boundary.search(my_string, offset)
end_boundary = end.start()
end_boundary
输出:33
end = boundary.search(my_string[::-1], len(my_string) - offset - 1)
start_boundary = len(my_string) - end.start()
start_boundary
输出:25
my_string[start_boundary:end_boundary]
输出:'问题'
但是,如果我有一个可能涉及多个字符的更复杂的正则表达式,则这种“反向”技术将不起作用。例如,如果我想匹配出现在指定偏移量之前的“ing”的第一个实例:
my_new_string = "Looking feeding dancing prancing"
offset = 16 # on the word dancing
m = re.match(r'(.*?ing)', my_new_string) # Except looking backwards
理想输出:喂食
我可能会使用其他方法(将文件分成几行,并向后迭代这些行),但向后使用正则表达式似乎是一个概念上更简单的解决方案。
【问题讨论】:
仅供参考,\b
匹配(或更准确地说,消耗)零个字符,而不是一个。
【参考方案1】:
使用肯定的lookbehind确保单词前至少有30个字符:
# re like: r'.*?(\w+)(?<=.30)'
m = re.match(r'.*?(\w+)(?<=.%d)' % (offset), my_string)
if m: print m.group(1)
else: print "no match"
对于另一个例子,消极的后视可能会有所帮助:
my_new_string = "Looking feeding dancing prancing"
offset = 16
m = re.match(r'.*(\b\w+ing)(?<!.%d)' % offset, my_new_string)
if m: print m.group(1)
首先贪心匹配任何字符但回溯,直到它无法向后匹配 16 个字符 ((?<!.16)
)。
【讨论】:
感谢后面的提示。我仍在尝试调整您的示例,以便我可以通过字符串“向后搜索”以获得更长的表达式。 (.*ing) 在我编辑的问题中 - 如果我要从偏移量向后寻找以 -ing 结尾的整个单词。 @Irwin,为该示例添加了解决方案【参考方案2】:我们可以利用 python 的正则表达式引擎对贪婪的偏好(有点,不是真的),并告诉它我们想要的是 尽可能多的字符,但不超过 30,然后...。
那么,一个合适的正则表达式可以是r'^.0,30(\b)'
。我们希望开始第一次捕获。
>>> boundary = re.compile(r'^.0,30(\b)')
>>> boundary.search("hello, world; goodbye, world; I am not a pie").start(1)
30
>>> boundary.search("hello, world; goodbye, world; I am not").start(1)
30
>>> boundary.search("hello, world; goodbye, world; I am").start(1)
30
>>> boundary.search("hello, world; goodbye, pie").start(1)
26
>>> boundary.search("hello, world; pie").start(1)
17
【讨论】:
+1。它同样适用于多字符序列;只需将(\b)
更改为(\b\w+\b)
。您可能需要调整限制以确保单词在 截止之前开始,而不是正好在它的位置(例如,0,29
在这种情况下)。
哦,是的,这是一个需要注意的问题——我给出的正则表达式适用于我对问题的陈述,也就是说,这是一个问题。跨度>
以上是关于您可以使用 Python 正则表达式从偏移量向后搜索吗?的主要内容,如果未能解决你的问题,请参考以下文章