18

我只是在学习Python,我似乎无法弄清楚正则表达式。

r1 = re.compile("$.pdf")
if r1.match("spam.pdf"):
    print 'yes'
else:
    print 'no'

我希望这段代码打印“是”,但它顽固地打印“否”。我还尝试了以下各项:

r1 = re.compile(r"$.pdf")

r1 = re.compile("$ .pdf")

r1 = re.compile('$.pdf')

if re.match("$.pdf", "spam.pdf")

r1 = re.compile(".pdf")

加上无数其他变化。我一直在寻找很长一段时间,但找不到/理解任何可以解决我的问题的东西。有人可以帮助新手吗?

4

5 回答 5

52

您已经尝试了所有变体,除了有效的变体。出现$在模式的末尾。此外,您需要转义句点,以便它实际上匹配一个句点(通常它匹配任何字符)。

r1 = re.compile(r"\.pdf$")

但是,更简单、更清晰的方法是使用字符串的.endswith()方法:

if filename.endswith(".pdf"):
    # do something

这样你就不必破译正则表达式来理解发生了什么。

于 2012-08-29T23:18:54.240 回答
25

的行为re.match()re.search()

有一个显着的区别:re.match()检查字符串的开头,您很可能正在寻找re.search().

两种方法的比较清楚地显示在名为“ search() vs. match() ”的 Python 文档章节中

正则表达式中的特殊字符

此外,正则表达式中字符的含义与您尝试使用它的含义不同(有关详细信息,请参阅正则表达式语法):

  • ^匹配开头:

    (插入符号。)匹配字符串的开头,并且在 MULTILINE 模式下也立即匹配每个换行符之后。

  • $匹配结尾:

    匹配字符串的结尾或字符串末尾的换行符之前,并且在MULTILINE模式下也匹配换行符之前。foo 匹配 '<code>foo' 和 '<code>foobar',而正则表达式foo$仅匹配 '<code>foo'。更有趣的是,在 'foo1\nfoo2\n' 中搜索 foo.$ 通常匹配 '<code>foo2',但在MULTILINEmode 中搜索 '<code>foo1';$在 ' ' 中搜索单个foo\n将找到两个(空)匹配项:一个在换行符之前,一个在字符串末尾。

完整答案

您正在寻找的解决方案可能是:

import re
r1 = re.compile("\.pdf$")  # regular expression corrected
if r1.search("spam.pdf"):  # re.match() replaced with re.search()
    print "yes"
else:
    print "no"

检查字符串是否以“ .pdf”结尾。与 kindall 的答案相同.endswith(),但如果 kindall 的答案适合您,请选择它(它更简洁,因为您可能根本不需要正则表达式)。

于 2012-08-29T23:24:06.160 回答
8

你的问题

$意思是“字符串的结尾”。所以,你需要一个正则表达式\.pdf$来匹配:

  1. 一个点 ( .),因为它是正则表达式中的特殊字符而被转义。
  2. 字符串“ pdf
  3. 字符串结束。

延伸阅读

正则表达式超越了语言、Python 或其他语言,所以你应该先阅读一些关于它们的教程。考虑正则表达式.info。这实际上不是 Python 问题,而是一个基本的正则表达式问题。

于 2012-08-29T23:21:49.963 回答
1

正则表达式$.pdf说“找到字符串的结尾,然后找到任何字符以及超出字符串结尾的任何字符,找到 ap、ad 和一个 f”。

正如所写,它无法合理地匹配任何东西。

但是,pdf$会匹配。

在这种特定情况下,您可能还想做 asearch而不是match,因为我相信 match 本质上锚定在字符串的开头。

于 2012-08-29T23:19:36.767 回答
1

我看到了 2 个快速的选择:

  • re.match(pattern='.*pdf$', string='filename.pdf')

    使用这个解决方案,我们必须指定我们不关心字符串如何开始。但是我们不能省略开头的表达式。使用时,re.match()您必须确保提供对整个字符串有效的正则表达式,即从索引 0 开始,请参阅https://docs.python.org/3/howto/regex.html#match-versus-search

  • re.search(pattern='\.pdf$', string='filename.pdf')

    我们不关心字符串是如何开始的,我们只是搜索一个以扩展名结尾的字符串

已回答已被接受,但我个人需要检查官方文档以明确这一点。

于 2017-12-14T15:11:50.757 回答