【问题标题】:Using ^ to match beginning of line in Python regex使用 ^ 匹配 Python 正则表达式中的行首
【发布时间】:2015-07-14 07:30:17
【问题描述】:

我正在尝试从 Thomson-Reuters Web of Science 中提取出版年 ISI 风格的数据。 “出版年”这一行看起来像这样(在一行的开头):

PY 2015

对于我正在编写的脚本,我定义了以下正则表达式函数:

import re
f = open('savedrecs.txt')
wosrecords = f.read()

def findyears():
    result = re.findall(r'PY (\d\d\d\d)', wosrecords)
    print result

findyears()

但是,这会产生误报结果,因为该模式可能出现在数据的其他地方。

所以,我只想匹配一行开头的模式。通常我会为此使用^,但r'^PY (\d\d\d\d)' 无法匹配我的结果。另一方面,使用\n 似乎可以满足我的要求,但这可能会给我带来更多麻烦。

【问题讨论】:

  • 使用re.MULTILINE改变^的语义:re.findall(r'^PY (\d\d\d\d)', wosrecords, re.MULTILINE)

标签: python regex


【解决方案1】:
re.findall(r'^PY (\d\d\d\d)', wosrecords, flags=re.MULTILINE)

应该工作

【讨论】:

    【解决方案2】:

    re.searchre.M 一起使用:

    import re
    p = re.compile(r'^PY\s+(\d{4})', re.M)
    test_str = "PY123\nPY 2015\nPY 2017"
    print(re.findall(p, test_str)) 
    

    IDEONE demo

    解释

    • ^ - 一行的开始(由于re.M
    • PY - 文字 PY
    • \s+ - 1 个或多个空格
    • (\d{4}) - 捕获组持有 4 个数字

    【讨论】:

    • 是的,这也应该可以。我错过的是 re.M 或 re.MULTILINE 标志,我不知道这会影响 ^。
    • 其实re.M的唯一作用就是:强制^$分别匹配行首和行尾(\n之前)。跨度>
    【解决方案3】:

    在这种特殊情况下,不需要使用正则表达式,因为搜索到的字符串始终是 'PY' 并且应该在行首,所以可以使用string.find 来完成这项工作。 find 函数返回子字符串在给定字符串或行中找到的位置,因此如果在字符串的开头找到它,则返回值为0(如果根本没有找到则返回-1),即:

    In [12]: 'PY 2015'.find('PY')
    Out[12]: 0
    
    In [13]: ' PY 2015'.find('PY')
    Out[13]: 1
    

    也许去掉空格是个好主意,例如:

    In [14]: '  PY 2015'.find('PY')
    Out[14]: 2
    
    In [15]: '  PY 2015'.strip().find('PY')
    Out[15]: 0
    

    接下来,如果只对年份感兴趣,则可以使用 split 提取它,即:

    In [16]: '  PY 2015'.strip().split()[1]
    Out[16]: '2015'
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-03-30
      • 1970-01-01
      • 1970-01-01
      • 2017-11-13
      • 2021-12-11
      相关资源
      最近更新 更多