【问题标题】:Filter out words depending on surrounding punctuation根据周围的标点符号过滤掉单词
【发布时间】:2021-03-29 15:11:21
【问题描述】:

目标:

我正在寻找一种方法来匹配或跳过单词,具体取决于它们是否被引号 ' '、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,这不是我想要的。

提前致谢!

【问题讨论】:

  • 如果字符串是blabla 'bla my word bla' blabla,匹配my word应该返回0还是1?
  • 确实很有趣的问题!它应该返回1,因为整个文本中的my word 没有直接被' '包围

标签: python regex regex-lookarounds quotation-marks


【解决方案1】:

我认为其中一种策略是使用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 个单词(如果它们前面有引号)标记)。

【讨论】:

  • 感谢您的详尽解释,感谢您的努力!我不知道pyparsing,但我以后可能不得不求助于它,因为除了提供的示例之外,我还需要满足其他要求,由于我没有进行所有各种单元测试,它变得更加棘手这里提到
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-26
  • 2012-07-03
  • 2014-03-08
相关资源
最近更新 更多