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

Python 不考虑空格查找正则表达式模式,python,regex,pandas,Python,Regex,Pandas,有字符串(即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,16 2.5807003.49 10/2020 35,65 4.7103181.69 10/2020 185,50 4.7197189.46 1 0/2020 185,50 4.7861901.25 10/2020 94,32 我需要的是从这些行中

有字符串(即
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,16
2.5807003.49 10/2020 35,65 4.7103181.69 10/2020 185,50 4.7197189.46 1 0/2020 185,50 4.7861901.25 10/2020 94,32

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

order\u id日期和

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\u id
    ,它们总是具有相同的结构
  • 日期中的月份可以有一位或两位数字
    
  • 日期本身可能(也可能不)包含空格!例如
    9/2020
    9/2020
    10/2020
    10/2020
  • sum
    总是在
    之后有两个数字,
    但不幸的是,也可能(或不)包含空格:
    24,54
    172,05
    185,50
    94,32
我是这样想的: 第一步是拆分订单。 显然,与给定的
订单id
相关的信息由
锚定——每行有4个订单和4个逗号。 所以,找到逗号,然后向前走两位数(不考虑空格),最后向后看,直到行的开头或上一个顺序的结尾。
但即使在这里,我也被卡住了,因为我不知道如何捕捉逗号后面的两位数字,而不考虑空格(如果有的话)。

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

(2\.5807003\.49|4\.7103181\.69|4\.7197189\.46|4\.7861901\.25)\s+([\d\s]+\/\d{4})\s+([\d\s]+,[\d\s]+)(?:\s|$)
演示:

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

(2\.5807003\.49|4\.7103181\.69|4\.7197189\.46|4\.7861901\.25)\s+([\d\s]+\/[\d\s]+)\s+([\d\s]+,[\d\s]+)(?:\s|$)
演示:

输入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
获取所有最终记录。所有三个必需的列都位于单独的捕获组中<代码>订单id
([\d\.]+)
。因为它没有空间,所以它是直截了当的<代码>日期是
(\d\s?\d?\s?\/\s?(?:\d\s?{3}\d)
在日期中的任何位置都可以有空格<代码>总和是
[\d\s]+,\s?\d\s?\d)
,逗号后有两位数字

req_vals = re.findall(r'([\d\.]+)\s*(\d\s?\d?\s?\/\s?(?:\d\s?){3}\d)\s*([\d\s]+,\s?\d\s?\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

使用```用于代码格式``code``我们在
2020
年也可以有空格,例如
2020
2020
2020
2020
?它只能是整个
日期
总和
中的一个空格。也就是说,
9/2020
9/2020
是可能的,但
0 9/20 0
不是。你应该(重新)阅读问题。1个空格内日期怎么样?