正则表达式使用 re.search() 匹配整个单词和标点符号

regex match whole word and punctuation with it using re.search()

正则表达式的新手。 目标 - 匹配可能包含“.”的整个单词或末尾带有“-”。我想保留它用于 .start() 和 .end() 位置计算。

txt = "The indian in. Spain."
pattern = "in."

x = re.search(r"\b" + pattern + r"\b" , txt)

print(x.start(), x.end())

我想要 'in.' 单词的位置,如突出显示的“The indian in. Spain.”。我使用的表达式给出了 Nonetype 对象的错误。 匹配“.”的表达式是什么?在上面的代码中?如果存在“-”而不是“.”,则相同

这里有两个问题。

  1. 在正则表达式中 . 是特殊的。它的意思是“匹配任何字符之一”。但是,您正在尝试使用它来匹配常规时间段。 (它确实会匹配那个,但它也会匹配其他所有内容。)相反,要匹配句点,您需要使用模式 \.。要更改它以匹配句点或连字符,您可以使用 class,例如 [-.].
  2. 您在模式末尾使用 \b 来匹配单词边界,但 \bdefined as being the boundary between a word character and a non-word character, and periods and spaces are both non-word characters. This means that Python won't find a match. Instead, you could use a lookahead assertion,它将匹配您想要的任何字符,但不会消耗字符串。

现在,要匹配整个单词 - 任何单词 - 您可以执行类似 \w+ 的操作,它匹配一个或多个单词字符。

此外,很可能无论如何都不会匹配,因此您应该使用 if 语句或 try 语句检查是否发生了匹配。把它们放在一起:

txt = "The indian in. Spain."
pattern = r"\w+[-.]"
x = re.search(r"\b" + pattern + r"(?=\W)", txt)
if x:
    print(x.start(), x.end())

编辑

上面的先行断言存在一个问题 - 它与字符串的末尾不匹配。这意味着,如果您的文本是 The rain in Spain.,那么它不会匹配 Spain.,因为在最后一个句点后没有非单词字符。

要解决此问题,您可以使用 negative lookahead assertion,当以下文本 包含模式且不使用字符串时匹配。

x = re.search(r"\b" + pattern + r"(?!\w)", txt)

当单词后面的字符不是单词字符(包括字符串结尾)时,这将匹配。