根据周围的标点符号过滤掉单词

问题描述

目标:

我正在寻找一种根据单词是否被引号 ' '、guillemets « » 或括号 ( ) 包围来匹配或跳过单词的方法

预期结果示例:

  • len(re.findall("my word","blablabla 'my word' blablabla")) 应该返回 0 因为从语言上讲my word =/= 'my word' 因此不应该匹配;

  • len(re.findall("'my word'","blablabla 'my word' blablabla")) 应该返回 1 因为从语言上讲'my word' = 'my word' 因此应该匹配;

  • 但这里有一个问题——len(re.findall("my word","blablabla «my word» blablabla"))len(re.findall("my word","blablabla (my word) blablabla")) 都应该返回 1

我的尝试:

我可以使用以下表达式(如果我错了,请纠正我),但我对如何实现它一无所知:(?<!\w)'[^ ].*?\w*?[^ ]'

我希望让以下代码 len(re.findall(r'(?<!\w)'+re.escape(myword)+r'(?!\w)',sentence)) - 我相信其目的是去除标点符号 - 考虑到上述所有情况。

目前,我的代码检测到 my word 中的 'my word' 这不是我想要的。

提前致谢!

解决方法

我认为其中一种策略是使用 negative look-ahead 功能:

my_word = "word"
r"(?!'" + my_word + "')[^']" + "my_word"

这应该可以check here完成这项工作。

由于否定前瞻不消耗字符,为了防止匹配,您需要使用 [^'] 来确保引号 ' 不是 my_word 之前的允许字符。开始枚举字符的 ^ 正是这个意思。

如果您想扩展不应将单词计为已找到的引号列表,只需将 ' 更改为不允许使用的字符列表:

r"(?!['`]" + my_word + "['`])[^'`]my_word"

值得注意的是,@Prasanna 问题中的示例将无法使用正则表达式进行匹配。您需要使用适当的解析器 - 例如pyparsing - 处理这种情况,因为正则表达式无法处理需要两个任意数量的字符才能匹配的匹配(例如,任意数量的“a”后跟相同数量的“b”字母)并且它将无法创建具有前瞻的通用正则表达式来处理 n 个单词然后 myword 并同时跳过 n 个单词,如果它们是前面加引号)。