Python 3.x 长正则表达式模式不是';他没有按计划工作

Python 3.x 长正则表达式模式不是';他没有按计划工作,python-3.x,regex,split,Python 3.x,Regex,Split,我的正则表达式模式在Python中似乎不起作用。此列用逗号与电子表格分隔,逗号之间有管道(|)也可以分隔内容。然而,我并不担心管道。我需要使用re.split()方法以逗号分隔字符串,但是,您会在示例中注意到,用户在第一个|之前的第一项中的字符串中输入逗号,因此我使用Regex来建立要查找的模式。但是,它不能正常工作,初学者可以使用另一组眼睛。我已经构建并运行了正则表达式来帮助我,解释似乎是正确的,但它仍然没有返回我期望的匹配数 我的正则表达式模式: “+\s\\\s\d\d\s\\\s\d\d

我的正则表达式模式在Python中似乎不起作用。此列用逗号与电子表格分隔,逗号之间有管道(
|
)也可以分隔内容。然而,我并不担心管道。我需要使用
re.split()
方法以逗号分隔字符串,但是,您会在示例中注意到,用户在第一个
|
之前的第一项中的字符串中输入逗号,因此我使用Regex来建立要查找的模式。但是,它不能正常工作,初学者可以使用另一组眼睛。我已经构建并运行了正则表达式来帮助我,解释似乎是正确的,但它仍然没有返回我期望的匹配数

我的正则表达式模式

“+\s\\\s\d\d\s\\\s\d\d\d\s\\\s\d\d\d\d\s\\\s.{2}\d\d\d\d\d\s\\s\d+.\d+?,”gm

我的样本测试字符串

ICS:E-利率折扣(85%);30よ5877 124242424242424242424247よ30 12424242417 124247 124247 124247 124247 12424周日周日1242410よ0000 | 2008<0.0,ICS:ICS:E-利率折扣(85%折扣(85%)12485%)12485%);30 124242424241012410 1241012424242410124101242424101242417 12417 1242417 12424242417 1242417 12417 124242417 1242417 12417 1242417 12417 12417 12417 12417 12417 12417 12417 1242417 12417 124电子费率折扣(85%)| 20 | 5877 | 0000 | IT0000 |-11475.0,ICCMS:基本维护| 70 | 5877 | 0000 | IT0000 | 12000.0,ICCMS:电子费率折扣(85%)| 70 12477 | 0000 | IT0000 |-10200.0,ITSM:笔记本电脑、台式机、计算机| 30 1240 1240 | IT0000 | 720400.0

我预计的匹配数:9个匹配

我获得的匹配数:1个匹配-(0-443):我从导出的匹配

不要在一开始就用贪婪的匹配来匹配所有内容,而要做一个惰性匹配
*?\s

我还使用了一个数量说明符,例如
{4}

*?\s\\s\d{2}\s\\s\d{4}\s\\s\d{4}\s\\s.{2}\d{4}\s\\s-?\d+\d+?

它有八个匹配项:

0-60集成电路:基本维护| 30 | 5877 | 0000 | IT0000 | 12000.0
60-126,ICS:电子利率折扣(85%)| 30 | 5877 | 0000 | IT0000 |-10200.0
126-186,ICS:基本维护| 40 | 5877 | 0000 | IT0000 | 9000.0
ICMS:电子利率折扣(85%)| 40 | 5877 | 0000 | IT0000 |-7650.0
252-313,ICS:基本维护| 20 | 5877 | 0000 | IT0000 | 13500.0
313-379,ICS:电子利率折扣(85%)| 20 | 5877 | 0000 | IT0000 |-11475.0
379-442,ICCMS:基本维护| 70 | 5877 | 0000 | IT0000 | 12000.0
442-510,ICCMS:电子费率折扣(85%)| 70 | 5877 | 0000 | IT0000 |-10200.0
最后一部分不匹配,因为缺少与
\s\d{4}\s
的匹配项。(以下以粗体显示的0000)

ITSM:笔记本电脑、台式机、计算机| 30 | 4400 | 0000 | IT0000 | 720400.0
不要在一开始就用贪婪的匹配来匹配所有东西
+\s
,而是做一个懒惰的匹配
*?\s

我还使用了一个数量说明符,例如
{4}

*?\s\\s\d{2}\s\\s\d{4}\s\\s\d{4}\s\\s.{2}\d{4}\s\\s-?\d+\d+?

它有八个匹配项:

0-60集成电路:基本维护| 30 | 5877 | 0000 | IT0000 | 12000.0
60-126,ICS:电子利率折扣(85%)| 30 | 5877 | 0000 | IT0000 |-10200.0
126-186,ICS:基本维护| 40 | 5877 | 0000 | IT0000 | 9000.0
ICMS:电子利率折扣(85%)| 40 | 5877 | 0000 | IT0000 |-7650.0
252-313,ICS:基本维护| 20 | 5877 | 0000 | IT0000 | 13500.0
313-379,ICS:电子利率折扣(85%)| 20 | 5877 | 0000 | IT0000 |-11475.0
379-442,ICCMS:基本维护| 70 | 5877 | 0000 | IT0000 | 12000.0
442-510,ICCMS:电子费率折扣(85%)| 70 | 5877 | 0000 | IT0000 |-10200.0
最后一部分不匹配,因为缺少与
\s\d{4}\s
的匹配项。(以下以粗体显示的0000)


ITSM:笔记本电脑、台式机、计算机| 30 | 4400 | 0000 | IT0000 | 720400.0
查看数据,如果您不担心管道,如果您想要9个匹配,您可以使用匹配所有值,而不是拆分并稍微缩短模式:

\w+:.*?\b\d+(?:\.\d+)(?=,|$)
  • \w+:
    匹配1+个单词字符和
  • *?
    匹配尽可能少的字符
  • \b\d+(?:\。\d+)
    单词边界,匹配1+位和可选的小数部分
  • (?=,|$)
    在右边断言一个逗号或字符串的结尾
|

输出

['ICS: Basic Maintenance | 30 | 5877 | 0000 | IT0000 | 12000.0',
 'ICS: E-Rate discount (85%) | 30 | 5877 | 0000 | IT0000 | -10200.0',
 'ICS: Basic Maintenance | 40 | 5877 | 0000 | IT0000 | 9000.0',
 'ICMS: E-Rate discount (85%) | 40 | 5877 | 0000 | IT0000 | -7650.0',
 'ICS: Basic Maintenance | 20 | 5877 | 0000 | IT0000 | 13500.0',
 'ICS: E-Rate discount (85%) | 20 | 5877 | 0000 | IT0000 | -11475.0',
 'ICCMS: Basic Maintenance | 70 | 5877 | 0000 | IT0000 | 12000.0',
 'ICCMS: E-Rate discount (85%) | 70 | 5877 | 0000 | IT0000 | -10200.0',
 'ITSM: Laptops, Desktops, Computers | 30 | 4400 | IT0000 | 720400.0']
['ICS: Basic Maintenance | 30 | 5877 | 0000 | IT0000 | 12000.0',
 'ICS: E-Rate discount (85%) | 30 | 5877 | 0000 | IT0000 | -10200.0',
 'ICS: Basic Maintenance | 40 | 5877 | 0000 | IT0000 | 9000.0',
 'ICMS: E-Rate discount (85%) | 40 | 5877 | 0000 | IT0000 | -7650.0',
 'ICS: Basic Maintenance | 20 | 5877 | 0000 | IT0000 | 13500.0',
 'ICS: E-Rate discount (85%) | 20 | 5877 | 0000 | IT0000 | -11475.0',
 'ICCMS: Basic Maintenance | 70 | 5877 | 0000 | IT0000 | 12000.0',
 'ICCMS: E-Rate discount (85%) | 70 | 5877 | 0000 | IT0000 | -10200.0',
 'ITSM: Laptops, Desktops, Computers | 30 | 4400 | IT0000 | 720400.0']

如果必须使用,可以使用捕获组来保留拆分值,并在逗号上拆分

匹配管道的完整模式:

import re
from pprint import pprint

pattern = r"(\w+:[^|]+\|\s\d\d\s\|(?:\s\d{4}\s\|){2}\s.{2}\d{4}\s\|\s-?\d+(?:\.\d+)?),"
s = "ICS: Basic Maintenance | 30 | 5877 | 0000 | IT0000 | 12000.0,ICS: E-Rate discount (85%) | 30 | 5877 | 0000 | IT0000 | -10200.0,ICS: Basic Maintenance | 40 | 5877 | 0000 | IT0000 | 9000.0,ICMS: E-Rate discount (85%) | 40 | 5877 | 0000 | IT0000 | -7650.0,ICS: Basic Maintenance | 20 | 5877 | 0000 | IT0000 | 13500.0,ICS: E-Rate discount (85%) | 20 | 5877 | 0000 | IT0000 | -11475.0,ICCMS: Basic Maintenance | 70 | 5877 | 0000 | IT0000 | 12000.0,ICCMS: E-Rate discount (85%) | 70 | 5877 | 0000 | IT0000 | -10200.0,ITSM: Laptops, Desktops, Computers | 30 | 4400 | IT0000 | 720400.0"

pprint(list(filter(None, re.split(pattern, s))))
输出

['ICS: Basic Maintenance | 30 | 5877 | 0000 | IT0000 | 12000.0',
 'ICS: E-Rate discount (85%) | 30 | 5877 | 0000 | IT0000 | -10200.0',
 'ICS: Basic Maintenance | 40 | 5877 | 0000 | IT0000 | 9000.0',
 'ICMS: E-Rate discount (85%) | 40 | 5877 | 0000 | IT0000 | -7650.0',
 'ICS: Basic Maintenance | 20 | 5877 | 0000 | IT0000 | 13500.0',
 'ICS: E-Rate discount (85%) | 20 | 5877 | 0000 | IT0000 | -11475.0',
 'ICCMS: Basic Maintenance | 70 | 5877 | 0000 | IT0000 | 12000.0',
 'ICCMS: E-Rate discount (85%) | 70 | 5877 | 0000 | IT0000 | -10200.0',
 'ITSM: Laptops, Desktops, Computers | 30 | 4400 | IT0000 | 720400.0']
['ICS: Basic Maintenance | 30 | 5877 | 0000 | IT0000 | 12000.0',
 'ICS: E-Rate discount (85%) | 30 | 5877 | 0000 | IT0000 | -10200.0',
 'ICS: Basic Maintenance | 40 | 5877 | 0000 | IT0000 | 9000.0',
 'ICMS: E-Rate discount (85%) | 40 | 5877 | 0000 | IT0000 | -7650.0',
 'ICS: Basic Maintenance | 20 | 5877 | 0000 | IT0000 | 13500.0',
 'ICS: E-Rate discount (85%) | 20 | 5877 | 0000 | IT0000 | -11475.0',
 'ICCMS: Basic Maintenance | 70 | 5877 | 0000 | IT0000 | 12000.0',
 'ICCMS: E-Rate discount (85%) | 70 | 5877 | 0000 | IT0000 | -10200.0',
 'ITSM: Laptops, Desktops, Computers | 30 | 4400 | IT0000 | 720400.0']

查看数据,如果您不担心管道,如果您想要9个匹配,您可以使用匹配所有值,而不是拆分并稍微缩短模式:

\w+:.*?\b\d+(?:\.\d+)(?=,|$)
  • \w+:
    匹配1+个单词字符和
  • *?
    匹配尽可能少的字符
  • \b\d+(?:\。\d+)
    单词边界,匹配1+位和可选的小数部分
  • (?=,|$)
    在右边断言一个逗号或字符串的结尾
|

输出

['ICS: Basic Maintenance | 30 | 5877 | 0000 | IT0000 | 12000.0',
 'ICS: E-Rate discount (85%) | 30 | 5877 | 0000 | IT0000 | -10200.0',
 'ICS: Basic Maintenance | 40 | 5877 | 0000 | IT0000 | 9000.0',
 'ICMS: E-Rate discount (85%) | 40 | 5877 | 0000 | IT0000 | -7650.0',
 'ICS: Basic Maintenance | 20 | 5877 | 0000 | IT0000 | 13500.0',
 'ICS: E-Rate discount (85%) | 20 | 5877 | 0000 | IT0000 | -11475.0',
 'ICCMS: Basic Maintenance | 70 | 5877 | 0000 | IT0000 | 12000.0',
 'ICCMS: E-Rate discount (85%) | 70 | 5877 | 0000 | IT0000 | -10200.0',
 'ITSM: Laptops, Desktops, Computers | 30 | 4400 | IT0000 | 720400.0']
['ICS: Basic Maintenance | 30 | 5877 | 0000 | IT0000 | 12000.0',
 'ICS: E-Rate discount (85%) | 30 | 5877 | 0000 | IT0000 | -10200.0',
 'ICS: Basic Maintenance | 40 | 5877 | 0000 | IT0000 | 9000.0',
 'ICMS: E-Rate discount (85%) | 40 | 5877 | 0000 | IT0000 | -7650.0',
 'ICS: Basic Maintenance | 20 | 5877 | 0000 | IT0000 | 13500.0',
 'ICS: E-Rate discount (85%) | 20 | 5877 | 0000 | IT0000 | -11475.0',
 'ICCMS: Basic Maintenance | 70 | 5877 | 0000 | IT0000 | 12000.0',
 'ICCMS: E-Rate discount (85%) | 70 | 5877 | 0000 | IT0000 | -10200.0',
 'ITSM: Laptops, Desktops, Computers | 30 | 4400 | IT0000 | 720400.0']

如果必须使用,可以使用捕获组来保留拆分值,并在逗号上拆分

匹配管道的完整模式:

import re
from pprint import pprint

pattern = r"(\w+:[^|]+\|\s\d\d\s\|(?:\s\d{4}\s\|){2}\s.{2}\d{4}\s\|\s-?\d+(?:\.\d+)?),"
s = "ICS: Basic Maintenance | 30 | 5877 | 0000 | IT0000 | 12000.0,ICS: E-Rate discount (85%) | 30 | 5877 | 0000 | IT0000 | -10200.0,ICS: Basic Maintenance | 40 | 5877 | 0000 | IT0000 | 9000.0,ICMS: E-Rate discount (85%) | 40 | 5877 | 0000 | IT0000 | -7650.0,ICS: Basic Maintenance | 20 | 5877 | 0000 | IT0000 | 13500.0,ICS: E-Rate discount (85%) | 20 | 5877 | 0000 | IT0000 | -11475.0,ICCMS: Basic Maintenance | 70 | 5877 | 0000 | IT0000 | 12000.0,ICCMS: E-Rate discount (85%) | 70 | 5877 | 0000 | IT0000 | -10200.0,ITSM: Laptops, Desktops, Computers | 30 | 4400 | IT0000 | 720400.0"

pprint(list(filter(None, re.split(pattern, s))))
输出

['ICS: Basic Maintenance | 30 | 5877 | 0000 | IT0000 | 12000.0',
 'ICS: E-Rate discount (85%) | 30 | 5877 | 0000 | IT0000 | -10200.0',
 'ICS: Basic Maintenance | 40 | 5877 | 0000 | IT0000 | 9000.0',
 'ICMS: E-Rate discount (85%) | 40 | 5877 | 0000 | IT0000 | -7650.0',
 'ICS: Basic Maintenance | 20 | 5877 | 0000 | IT0000 | 13500.0',
 'ICS: E-Rate discount (85%) | 20 | 5877 | 0000 | IT0000 | -11475.0',
 'ICCMS: Basic Maintenance | 70 | 5877 | 0000 | IT0000 | 12000.0',
 'ICCMS: E-Rate discount (85%) | 70 | 5877 | 0000 | IT0000 | -10200.0',
 'ITSM: Laptops, Desktops, Computers | 30 | 4400 | IT0000 | 720400.0']
['ICS: Basic Maintenance | 30 | 5877 | 0000 | IT0000 | 12000.0',
 'ICS: E-Rate discount (85%) | 30 | 5877 | 0000 | IT0000 | -10200.0',
 'ICS: Basic Maintenance | 40 | 5877 | 0000 | IT0000 | 9000.0',
 'ICMS: E-Rate discount (85%) | 40 | 5877 | 0000 | IT0000 | -7650.0',
 'ICS: Basic Maintenance | 20 | 5877 | 0000 | IT0000 | 13500.0',
 'ICS: E-Rate discount (85%) | 20 | 5877 | 0000 | IT0000 | -11475.0',
 'ICCMS: Basic Maintenance | 70 | 5877 | 0000 | IT0000 | 12000.0',
 'ICCMS: E-Rate discount (85%) | 70 | 5877 | 0000 | IT0000 | -10200.0',
 'ITSM: Laptops, Desktops, Computers | 30 | 4400 | IT0000 | 720400.0']

谢谢你,普拉纳夫,你做得很好。延迟匹配和
\d
的复制确实使我的模式过于复杂。用
{4}
替换是有帮助的。谢谢Pranav,它工作得非常出色。延迟匹配和
\d
的复制确实使我的模式过于复杂。用
{4}
替换是有帮助的。@mraguda看到这个模式在这个问题上失败了吗@Thefourthbird@mraguda但这是一个不同的数据样本。请尝试
[^,].\b\d+(?:\。\d+(=,|$)
您说得对--删除了