我想匹配一个单词,然后在它之前得到一切,直到第一次出现一个句号或字符串的开头.
例如,给定此字符串并搜索单词"regex":
s = 'Do not match this. Or this. Or this either. I like regex. It is hard, but regex is also rewarding.'
Run Code Online (Sandbox Code Playgroud)
它应该返回:
>> I like regex.
>> It is hard, but regex is also rewarding.
Run Code Online (Sandbox Code Playgroud)
我试图让我的头脑前瞻和后视,但(看起来)你不能轻易回头直到你击中某个东西,只有它紧挨着你的模式.我可以非常接近这个:
pattern = re.compile(r'(?:(?<=\.)|(?<=^))(.*?regex.*?\.)')
Run Code Online (Sandbox Code Playgroud)
但它给了我第一个时期,然后是"正则表达式":
>> Do not match this. Or this. Or this either. I like regex. # no!
>> It is hard, but regex is also rewarding. # correct
Run Code Online (Sandbox Code Playgroud)
您不需要使用外观来做到这一点.被否定的角色类是你最好的朋友:
(?:[^\s.][^.]*)?regex[^.]*\.?
Run Code Online (Sandbox Code Playgroud)
要么
[^.]*regex[^.]*\.?
Run Code Online (Sandbox Code Playgroud)
这样你就可以在单词"regex"之前取任何字符,并禁止任何这些字符成为一个点.
第一个图案左边是白色空格,第二个是更基本的.
关于你的模式:
不要忘记正则表达式引擎尝试从字符串的左侧到右侧的每个位置成功.这就是为什么类似的东西(?:(?<=\.)|(?<=^)).*?regex并不总是返回点或字符串的开头和单词"regex"之间的最短子串,即使你使用非贪婪的量词.最左边的位置总是获胜,非贪婪的量词会占用字符,直到下一个子模式成功.
另外,再一次,否定的字符类可能是有用的:
缩短(?:(?<=\.)|(?<=^))你可以写(?<![^.])