查找正则表达式模式,而不考虑空格



有字符串(是pandas数据框的行):

2.5807003.49 9/2020 24,54 4.7103181.69 9 /2020 172,05 4.7197189.46 09/2020 172,0 5 4.7861901.25 9/2020 8 9,162.5807003.49 10/2020 35,65 4.7103181.69 10/2020 185,50 4.7197189.46 1 0/2020 185,5 0 4.7861901.25 10/2020 94 ,32

我需要从这些行中提取以下信息(这里的逗号是小数分隔符):

order_id date sum
2.5807003.49 09/2020 24,54
4.7103181.69 09/2020 172,05
4.7197189.46 09/2020 172,05
4.7861901.25 09/2020 89,16
2.5807003.49 10/2020 35,65
4.7103181.69 10/2020 185,50
4.7197189.46 10/2020 185,50
4.7861901.25 10/2020 94,32

  • 只有 4 个不同的order_id,它们始终具有相同的结构;
  • date中的月份可以有一位或两位数;
  • 日期本身可能(也可能不包含)空格! 例如9 /20209/202010/20201 0/2020;
  • sum,后面总是有两个数字,但不幸的是,可能(或不包含)也包含空格:24,54172,0 5185,5 094 ,32

我是这样想的: 第一步是拆分订单。 显然,与给定order_id相关的信息由,锚定 - 每行有 4 个订单和 4 个逗号。 因此,找到逗号,然后在逗号后面前进两位数字(不考虑空格),最后回头看直到行首或前一个顺序的结尾。 但即使在这里,我也被困住了,因为我不明白如何捕获逗号后的两位数字,而不管空格(如果有的话)。

输入 df

vals
0   2.5807003.49 9/2020 24,54 4.7103181.69 9 /2020 172,0 5 4.7197189.46 09/2020 172,0 5
1   4.7861901.25 9/2020 8 9,16
2   2.5807003.49 10/2020 35,65 4.7103181.69 10/2020 185,50 4.7197189.46 1 0/2020 185,5 0
3   4.7861901.25 10/2020 94 ,32

现在,由于预期 df 中的多行在原始 df 中合并为一行,因此最好先将整个vals列转换为单个字符串

str1 = "n".join(df['vals'].values)
str1
2.5807003.49 9/2020 24,54 4.7103181.69 9 /2020 172,0 5 4.7197189.46 09/2020 172,0 5
4.7861901.25 9/2020 8 9,16
2.5807003.49 10/2020 35,65 4.7103181.69 10/2020 185,50 4.7197189.46 1 0/2020 185,5 0
4.7861901.25 10/2020 94 ,32

现在使用findall获取所有最终记录。所有三个必需列都位于单独的捕获组中。order_id([d.]+).由于它没有空间,所以它是直截了当的。date(ds?d?s?/s?(?:ds?){3}d)空间可以位于日期中的任何位置。sum是逗号后有两个数字的[ds]+,s?ds?d)

req_vals = re.findall(r'([d.]+)s*(ds?d?s?/s?(?:ds?){3}d)s*([ds]+,s?ds?d)',str1)
req_vals
[('2.5807003.49', '9/2020', '24,54'),
('4.7103181.69', '9 /2020', '172,0 5'),
('4.7197189.46', '09/2020', '172,0 5'),
('4.7861901.25', '9/2020', '8 9,16'),
('2.5807003.49', '10/2020', '35,65'),
('4.7103181.69', '10/2020', '185,50'),
('4.7197189.46', '1 0/2020', '185,5 0'),
('4.7861901.25', '10/2020', '94 ,32')]

最后,在输出数据帧中,可以删除空间。

final_df = (pd.DataFrame(req_vals, columns=['order_id', 'date', 'sum'])
.replace(r's', '', regex=True))
final_df
order_id      date    sum
0   2.5807003.49    9/2020  24,54
1   4.7103181.69    9/2020  172,05
2   4.7197189.46    09/2020 172,05
3   4.7861901.25    9/2020  89,16
4   2.5807003.49    10/2020 35,65
5   4.7103181.69    10/2020 185,50
6   4.7197189.46    10/2020 185,50
7   4.7861901.25    10/2020 94,32

一个可用于提供的示例的正则表达式:

(2.5807003.49|4.7103181.69|4.7197189.46|4.7861901.25)s+([ds]+/d{4})s+([ds]+,[ds]+)(?:s|$)

演示:https://regex101.com/r/VLc53D/1/

或者,如果一年中可以有一个空间:

(2.5807003.49|4.7103181.69|4.7197189.46|4.7861901.25)s+([ds]+/[ds]+)s+([ds]+,[ds]+)(?:s|$)

演示:https://regex101.com/r/LjcF3Q/1/

最新更新