当前位置: 首页 > 面试题库 >

以特殊字符开头或结尾的单词的单词边界会产生意外结果

松雅健
2023-03-14
问题内容

说我想匹配短语Sortes\index[persons]{Sortes}中短语的存在test Sortes\index[persons]{Sortes} text

使用pythonre我可以做到这一点:

>>> search = re.escape('Sortes\index[persons]{Sortes}')
>>> match = 'test Sortes\index[persons]{Sortes} text'
>>> re.search(search, match)
<_sre.SRE_Match object; span=(5, 34), match='Sortes\\index[persons]{Sortes}'>

这行得通,但我想避免使用搜索模式Sortes对短语给出肯定的结果test Sortes\index[persons]{Sortes} text

>>> re.search(re.escape('Sortes'), match)
<_sre.SRE_Match object; span=(5, 11), match='Sortes'>

所以我使用这种\b模式,像这样:

search = r'\b' + re.escape('Sortes\index[persons]{Sortes}') + r'\b'
match = 'test Sortes\index[persons]{Sortes} text'
re.search(search, match)

现在,我没有比赛。

如果搜索模式不包含任何字符[]{},则可以使用。例如:

>>> re.search(r'\b' + re.escape('Sortes\index') + r'\b', 'test Sortes\index test')
<_sre.SRE_Match object; span=(5, 17), match='Sortes\\index'>

另外,如果我删除final r'\b',那么它也可以工作:

re.search(r'\b' + re.escape('Sortes\index[persons]{Sortes}'), 'test Sortes\index[persons]{Sortes} test')
<_sre.SRE_Match object; span=(5, 34), match='Sortes\\index[persons]{Sortes}'>

此外,文档中还提到了\b

请注意,形式上,\ b定义为\ w和\ W字符之间的边界(反之亦然)或\ w与字符串的开头/结尾之间的边界。

所以,我想替换最后\b(\W|$)

>>> re.search(r'\b' + re.escape('Sortes\index[persons]{Sortes}') + '(\W|$)', 'test Sortes\index[persons]{Sortes} test')
<_sre.SRE_Match object; span=(5, 35), match='Sortes\\index[persons]{Sortes} '>

瞧,它起作用了!这里发生了什么?我想念什么?


问题答案:

查看单词边界匹配什么:

单词边界可以出现在以下三个位置之一:

  • 如果字符串中的第一个字符是单词字符,则在字符串中第一个字符之前。
  • 如果字符串中的最后一个字符是单词字符,则在字符串的最后一个字符之后。
  • 字符串中的两个字符之间,其中一个是单词字符,另一个不是单词字符。

在您的模式中,}\b只有在单词char }(字母,数字或_)之后才匹配。

使用时,(\W|$)您需要 显式 使用非单词或字符串结尾。

在这些情况下,我总是建议基于否定环顾的字词边界:

re.search(r'(?<!\w){}(?!\w)'.format(re.escape('Sortes\index[persons]{Sortes}')), 'test Sortes\index[persons]{Sortes} test')

在此,(?<!\w)如果当前位置的左侧紧邻有一个字符char
,则负向后搜索将使匹配失败;如果当前位置的右侧紧邻有一个字符char,则(?!\w)负向搜索将使匹配失败。

实际上,可以很容易地进一步自定义这些环视模式(例如,只有在模式周围有 字母
时才使匹配失败,请使用[^\W\d_]代替\w,或者如果只允许空格周围的匹配,请使用(?<!\S)/(?!\S)环视边界)。



 类似资料:
  • 我想用另一个数字替换字符串,它是一个方括号。我正在使用regex替换方法。 示例输入:

  • 使用正则表达式匹配表达式 为什么这两个示例匹配如下(突出显示): c# < code>a #b #c #d 具体来说,为什么第一个字符串不匹配包含最后一个#之前的所有内容? 由于单词边界(\b)是零宽度匹配,可以在单词字符(\w)和非单词字符(\ w)之间匹配,或者在单词字符和字符串的开始或结束之间匹配,我不确定以非单词字符结束表达式会如何影响匹配。

  • 有人能帮我写代码吗?如何在字符串文本中搜索单词,此单词以“.”结尾java中的“或” 我不想这样搜索来找到它

  • 我被分配了一个任务,从数组列表中返回以特定字母开头的单词,但是我选择了字母c;我被告知我可以用另一种方式做到这一点,除了专门返回每个以字母开头的元素和许多println之外,我不知道除了使用ArrayList startswith方法之外,还有什么其他方法可以做到这一点,有人愿意启发我吗? }

  • 我得到以下字符串: 我想从里面拿走食物和饮料。 我尝试了以下代码: 但它给人的感觉是,食物很刺激,喝了很多,离食物很近,三个和四个。

  • 我必须在数据库中找到所有有模式的记录。如果字段中的任何单词以特定字符串结尾。比如“is”: 所以像%is%或%is这样的简单操作是无效的。有没有什么正则表达式可以帮我做这件事?我也可以在PHP中使用LIKE%is%和filtring获得所有记录,但仍然没有任何线索如何。我有结束字符串的解决方案,但没有单词。