匹配点的正则表达式

152

想知道使用Python从"blah blah blah test.this@gmail.com blah blah"中匹配"test.this"的最佳方法是什么?

我尝试了re.split(r"\b\w.\w@")


\w 只匹配单个字符 - 你可能想要使用 \w+ - Peter Boughton
3
如果你正在寻找电子邮件验证正则表达式,这里有一个邮件验证正则表达式链接。请参考。 - chucksmash
8个回答

245

正则表达式中的 . 是一个元字符,它可以匹配任意字符。如果要在Python原始字符串(r"" 或者 r'')中匹配一个字面上的点,你需要转义它,因此使用 r"\."


11
除非正则表达式存储在Python的常规字符串中,否则您需要使用双\ (\\)。因此,这些表达式都是等价的:'\\.'"\\."r'\.'r"\."。详情请参见:https://dev59.com/pFQK5IYBdhLWcg3wKc3k#52335971。 - Gabriel Staples
我已经添加了一个答案:https://dev59.com/a2Yr5IYBdhLWcg3wDGHP#66666859。 - Gabriel Staples
@GabrielStaples 微小的问题--r"..." 语法是 Python 中的 "原始" 字符串,而不是 "常规" 字符串。 - GrandOpener
1
@GrandOpener,正确的,正如我在我的回答中所解释的那样(请看一下)。请再次阅读我的上面的评论。我说过普通字符串需要双斜杠:'\\.'"\\.",而原始字符串需要单斜杠:r'\.'r"\.",这也是我评论的全部意图。这个答案没有表明清楚。我想在我的评论中澄清这一点,为了那些使用普通字符串的人,因为这个答案只适用于原始字符串。 - Gabriel Staples
1
@GrandOpener,我已经更新了Yuushi的回答,以明确他的答案仅适用于原始字符串。如果Yuushi希望展示如何在常规字符串中需要两个反斜杠,则可以编辑他的回答并链接到我的回答。(我尽量最少修改他的回答。) - Gabriel Staples
@GabrielStaples 哦,我现在明白你的意思了。我第一次阅读你的评论时没有正确解析“除非...在这种情况下”的含义。那就算了! - GrandOpener

59
在正则表达式中,您需要转义点号 "\." 或在字符类 "[]" 中使用它 "[.]",因为它是正则表达式中的元字符,可以匹配任何字符。
另外,您需要使用 "\w+" 而不是 "\w" 来匹配一个或多个单词字符。
如果要获取 "test.this" 内容,则不需要使用 splitsplit 将在字符串周围拆分您的字符串。例如:
>>> re.split(r"\b\w+\.\w+@", s)
['blah blah blah ', 'gmail.com blah blah']
你可以使用 re.findall 方法:
>>> re.findall(r'\w+[.]\w+(?=@)', s)   # look ahead
['test.this']
>>> re.findall(r'(\w+[.]\w+)@', s)     # capture group
['test.this']

2
+1 代表字符类。使用 Jenkinsfile 中的 gcovr 并尝试排除点目录,但 Jenkins 不理解转义序列。字符类效果很好。 - Jonathan E. Landrum

15

"默认情况下,点(.)匹配除换行符以外的任何字符。如果指定了DOTALL标志,则该模式将匹配包括换行符在内的任何字符。"(Python文档)

因此,如果您想要直接匹配点号,请将其放在方括号中:

>>> p = re.compile(r'\b(\w+[.]\w+)')
>>> resp = p.search("blah blah blah test.this@gmail.com blah blah")
>>> resp.group()
'test.this'

3

这是我对 @Yuushi 的主要回答的补充:

概述

以下内容是不被允许的。

'\.'   # NOT a valid escape sequence in **regular** Python single-quoted strings
"\."   # NOT a valid escape sequence in **regular** Python double-quoted strings

他们会导致如下警告:

DeprecationWarning: 无效的转义序列 \.

然而,所有这些都是允许的且等价的:

# Use a DOUBLE BACK-SLASH in Python _regular_ strings
'\\.'  # **regular** Python single-quoted string
"\\."  # **regular** Python double-quoted string

# Use a SINGLE BACK-SLASH in Python _raw_ strings 
r'\.'  # Python single-quoted **raw** string
r"\."  # Python double-quoted **raw** string

解释

请记住,如果在正常字符串('some string'"some string")中使用而不是原始字符串r'some string'r"some string"),则Python中的反斜杠(\)字符本身必须进行转义。因此,请注意您正在使用的字符串类型。为了在正常python字符串中转义正则表达式中的点或句号(.),因此,您还必须通过使用双反斜杠(\\)来转义反斜杠,从而使正则表达式中的.的总转义序列为:\\.,如上例所示。

参考资料

  1. 主要和官方参考资料: https://docs.python.org/3/reference/lexical_analysis.html#string-and-bytes-literals enter image description here
  2. [由@Sean Hammond回答] 如何在Python中修复“<string> DeprecationWarning: invalid escape sequence”问题?

    如果你想在字符串中放置一个字面意义的 \ ,你必须使用 \\


1

为了转义包括点在内的字符串变量中的非字母数字字符,可以使用re.escape

import re

expression = 'whatever.v1.dfc'
escaped_expression = re.escape(expression)
print(escaped_expression)

输出:

whatever\.v1\.dfc

您可以使用转义表达式来直接查找/匹配字符串。


0
首先,你需要构建你的正则表达式字符串。 例如,这个正则表达式可以满足你的需求:

^.*?\btest\b\.\bthis\b.*?

接下来你需要将它转化为Python代码:
import re

input_string = "blah blah blah test.this@gmail.com blah blah"
regex_string = "^.*?\\btest\\b\\.\\bthis\\b.*?"
if re.search(regex_string, input_string):
    print("match :-)")
else:
    print("no match :-(")

要理解正则表达式的作用,你可以在regex101.com上进行实验。

-3

这个表达式,

(?<=\s|^)[^.\s]+\.[^.\s]+(?=@)

对于那些特定类型的输入字符串,这也可能有效。

演示

测试

import re

expression = r'(?<=^|\s)[^.\s]+\.[^.\s]+(?=@)'
string = '''
blah blah blah test.this@gmail.com blah blah
blah blah blah test.this @gmail.com blah blah
blah blah blah test.this.this@gmail.com blah blah
'''

matches = re.findall(expression, string)

print(matches)

输出

['test.this']

如果您想简化/修改/探索表达式,可以在regex101.com的右上方面板中找到解释。如果您愿意,您还可以在this link中观看它如何匹配一些示例输入。



-4
在JavaScript中,您必须使用\\。来匹配一个点。
例如:
"blah.tests.zibri.org".match('test\\..*')
null

并且

"blah.test.zibri.org".match('test\\..*')
["test.zibri.org", index: 5, input: "blah.test.zibri.org", groups: undefined]

1
它要求使用Python而不是JS。 - pl-jay

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接