问题描述
我正在从包含日期的HTML元素中抓取字符串。
我要执行的操作是使用正则表达式提取日期,然后使用datetime
模块将其转换为其他格式。
字符串遵循以下格式:
Date first available at Amazon.ca: Nov. 23 2017
Date first available at Amazon.ca: March 27 2017
Date first available at Amazon.ca: March 6 2018
棘手的事情是,只有长名称的月份被缩写。
Jan.
Feb.
March
April
May
June
July
Aug.
Sept.
Oct.
Nov.
Dec.
我的第一个想法是选择除Date first available at Amazon.ca:
所有内容,但是显然,这比我最初想象的要难一些。
我的下一个想法是类似r'^(J|F|M|A|S|O|De)'
,但这显然不起作用,因为月份不在字符串的开头。
现在,我被想法所困扰。
显然,类似以下正则表达式的东西会起作用,但似乎过于冗长。
r'(Jan.|Feb.|March|April|May|June|July|Aug.|Sept.|Oct.|Nov.|Dec.)[\\d\\s]+'
1楼
您可以通过搜索带有可能的"."
字母来搜索月,日和年"."
:
import re, datetime
months = {b:a for a, b in enumerate(['Jan.', 'Feb.', 'March', 'April', 'May', 'June', 'July', 'Aug.', 'Sept.', 'Oct.', 'Nov.', 'Dec.'], 1)}
def convert_date(d:str) -> str:
month, day, year = d.split()
return datetime.datetime(int(year), months[month], int(day))
data = ['Date first available at Amazon.ca: Nov. 23 2017', 'Date first available at Amazon.ca: March 27 2017', 'Date first available at Amazon.ca: March 6 2018']
new_data = [re.findall('[a-zA-Z]+\.*\s\d+\s\d+$', i) for i in data]
final_results = [convert_date(i[0]) for i in new_data if i]
输出:
[datetime.datetime(2017, 11, 23, 0, 0), datetime.datetime(2017, 3, 27, 0, 0), datetime.datetime(2018, 3, 6, 0, 0)]
时序:
import time
def timeit(f):
_t1 = time.time()
_ = f()
print(f'{f.__name__}: completed in {time.time()-_t1}')
@timeit
def ajax1234():
new_data = [re.findall('[a-zA-Z]+\.*\s\d+\s\d+$', i) for i in data]
@timeit
def anthony():
t = [re.findall('(Jan.|Feb.|March|April|May|June|July|Aug.|Sept.|Oct.|Nov.|Dec.)[\d\s]+', i) for i in data]
输出:
ajax1234: completed in 4.982948303222656e-05
anthony: completed in 3.314018249511719e-05
2楼
您可以尝试以下方法:
import re
dlist = [
"Date first available at Amazon.ca: Nov. 23 2017",
"Date first available at Amazon.ca: March 27 2017",
"Date first available at Amazon.ca: March 6 2018"]
print([re.search(r"(?<=\: )[a-zA-Z]+\.*[0-9 ]+" , each).group(0) for each in dlist])
3楼
所以这是我的完整解决方案。
first_available = ff.find_elements(By.XPATH, '//li[contains(., "Date first available")]')
regex_first_available = re.compile(r'(Jan|Feb|March|April|May|June|July|Aug|Sept|Oct|Nov|Dec)[\d\s]+')
if len(first_available) > 0:
first_available = regex_first_available.search(first_available[0].text).group(0)
else:
first_available = ff.find_element(By.XPATH, '//td[text()="Date First Available"]/following-sibling::td[1]').text.replace('.', '')
try:
first_available = datetime.datetime.strptime(first_available, '%b %d %Y').strftime('%Y-%m-%d')
except ValueError:
first_available = datetime.datetime.strptime(first_available, '%B %d %Y').strftime('%Y-%m-%d')
如果有人改进此方法,我将选择您的解决方案作为答案。