Python 中的正则表达式使用月份缩写
Regular Expression in Python using months abbreviation
我有几千行,例如:
"The sequence 1,-2,-1,2,1,-2,-1,2,... with g.f. (1-2x)/(1+x^2) has a(n) = cos(Pi*n/2)-2*sin(Pi*n/2). - Paul Barry, Oct 18 2004"
我需要找到显示为 'Aug 03' 等缩写的日期的位置(如果有的话)。出于这个原因,我编写了一个函数 _find_all_positions
,它在 for 循环中将一个字符串和一个从 'Jan 01' 到 'Dec 31' 的日期说明符作为输入。
def _add_zero(value: int) -> str:
"""add zero to number with digits < 2"""
value_str = str(value)
digits = len(value_str)
if digits < 2:
value_str = '0' + value_str
return value_str
def get_date() -> list:
"""Get dates for author(s) search, from ' Jan 01' to ' Dec 31' """
dates = list()
months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
for month in months:
for day in range(1, 32):
dates.append(' ' + month + ' ' + ParserUtilities._add_zero(day))
return dates
def _find_all_positions(string: str, sub: str):
"""Find all occurrences of a substring in a string"""
start = 0
while True:
start = string.find(sub, start)
if start == -1:
return
yield start
start += len(sub) # use start += 1 to find overlapping matches
任务很慢,我想知道 Regular Expression
是否可以加快搜索速度
这里有一个 regex 的方法,它看起来是一个大写字母,后面跟着 2 个小写字母。然后是 space 和 2 位数字:
import calendar
import re
# first one is empty string, we slice that
months = tuple(calendar.month_abbr)[1:] # ("Jan", "Feb", ...)
pattern = re.compile(r"[A-Z][a-z]{2} \d{2}")
result = [match.start()
for match in re.finditer(pattern, seq)
if match.group().startswith(months)]
给出问题中字符串的 [111]
。 re.finditer
查找所有可能的匹配项和 returns 一个迭代器,迭代器在迭代时给出一个 re.Match
对象,我们查询其 start
方法以获取匹配项的位置。由于 [A-Z][a-z]{2}
可以匹配除月份以外的其他月份,因此我们检查匹配是否以任何月份开头。如果找不到匹配项,result
将是一个空列表。
您可以将所有月份放在一个正则表达式中:
def find_all_positions(text):
for match in re.finditer('(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) ([012][0-9]|30|31)', text):
yield math.start()
我有几千行,例如:
"The sequence 1,-2,-1,2,1,-2,-1,2,... with g.f. (1-2x)/(1+x^2) has a(n) = cos(Pi*n/2)-2*sin(Pi*n/2). - Paul Barry, Oct 18 2004"
我需要找到显示为 'Aug 03' 等缩写的日期的位置(如果有的话)。出于这个原因,我编写了一个函数 _find_all_positions
,它在 for 循环中将一个字符串和一个从 'Jan 01' 到 'Dec 31' 的日期说明符作为输入。
def _add_zero(value: int) -> str:
"""add zero to number with digits < 2"""
value_str = str(value)
digits = len(value_str)
if digits < 2:
value_str = '0' + value_str
return value_str
def get_date() -> list:
"""Get dates for author(s) search, from ' Jan 01' to ' Dec 31' """
dates = list()
months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
for month in months:
for day in range(1, 32):
dates.append(' ' + month + ' ' + ParserUtilities._add_zero(day))
return dates
def _find_all_positions(string: str, sub: str):
"""Find all occurrences of a substring in a string"""
start = 0
while True:
start = string.find(sub, start)
if start == -1:
return
yield start
start += len(sub) # use start += 1 to find overlapping matches
任务很慢,我想知道 Regular Expression
是否可以加快搜索速度
这里有一个 regex 的方法,它看起来是一个大写字母,后面跟着 2 个小写字母。然后是 space 和 2 位数字:
import calendar
import re
# first one is empty string, we slice that
months = tuple(calendar.month_abbr)[1:] # ("Jan", "Feb", ...)
pattern = re.compile(r"[A-Z][a-z]{2} \d{2}")
result = [match.start()
for match in re.finditer(pattern, seq)
if match.group().startswith(months)]
给出问题中字符串的 [111]
。 re.finditer
查找所有可能的匹配项和 returns 一个迭代器,迭代器在迭代时给出一个 re.Match
对象,我们查询其 start
方法以获取匹配项的位置。由于 [A-Z][a-z]{2}
可以匹配除月份以外的其他月份,因此我们检查匹配是否以任何月份开头。如果找不到匹配项,result
将是一个空列表。
您可以将所有月份放在一个正则表达式中:
def find_all_positions(text):
for match in re.finditer('(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) ([012][0-9]|30|31)', text):
yield math.start()