使用正则表达式添加空组
Use regex to add empty groups
我是初学者 python 程序员。我正在尝试使用正则表达式来构建要附加到列表的组。我不确定我想做的事情是否可以用一个正则表达式覆盖,或者我是否需要通过多个正则表达式传递文本。
测试数据:
亚达亚达 0.003 40 40.00
yadayada ya 55
yaaaaaaya 100.0000 4
我的正则表达式:
(\w+ *\w* *\w*) (\d*\.*\d*) *(\d*\.*\d*) *(\d*\.*\d*)\n
我得到的群组:
'yada yada','0.003','40','40.00'
'yadayada ya','55',空,空
'yaaaaaaya','100.0000','4',空
但我想要的组是:
'yada yada','0.003','40','40.00'
'yadayada ya',空,空,'55'
'yaaaaaaya',空,'100.0000','4'
是否可以更改正则表达式以将空 (\d*.*\d*) 组引入那些少于 3 个组的行中?这样数字组就是"right-justified"?
我试过添加 ?到前两个 (\d*) 组的末尾,但得到相同的空组。
最简单的方法来执行您通俗地描述为 "right-justifying" 匹配,即。 e.优先匹配后面的可选子表达式,就是把可选成分的"greediness"反转过来。在 Python 正则表达式中,这是通过向每个量化元素添加 ?
来实现的:
(\w+ *\w* *\w*) (\d*?\.*?\d*?) *?(\d*?\.*?\d*?) *?(\d*?\.*?\d*?)\n
请注意,您的表达很自由,不会验证某些格式不正确的输入。如果这对你有用,那很好,否则你可能需要考虑将某些部分放在可选组中,例如 (| \d+(?:\.\d+)?)
以延迟匹配 space 和数字,例如(构造 (|x)
相当于((?:x)??)
).
编辑:正如 Tim 指出的那样,此正则表达式的缺点不仅仅是宽容,而且如果输入的格式稍有不正确,可能会引发灾难性的回溯。如果您打算坚持使用这种方法,我会推荐一些更精确的方法:
(\w+(?: \w+){0,2}) (|\d+(?:\.\d+)?) ?(|\d+(?:\.\d+)?) ?(|\d+(?:\.\d+)?)\n
它仍然可以匹配格式错误的输入,但至少现在更严格了。
您的正则表达式有几个问题,其中之一是 catastrophic backtracking 的高风险,因为正则表达式引擎需要在不匹配的情况下测试的排列数量呈指数级增长。另一个问题是 \w
也会匹配数字,因此第一组可能包含您不希望它包含的数字。
此外,对于这样的 "dynamically growing" 正则表达式,您需要 "match continuation" 功能,例如 \G
或 \K
锚点,但 Python 确实需要不支持那些。
最好的方法是将字符串 .split()
转换为子字符串,然后检查每个子字符串是否包含数字(例如通过 try
ing 将其转换为 float
) 并据此行事。
额外的好处:你有一个可读的Python脚本而不是一个非常复杂的正则表达式。
我是初学者 python 程序员。我正在尝试使用正则表达式来构建要附加到列表的组。我不确定我想做的事情是否可以用一个正则表达式覆盖,或者我是否需要通过多个正则表达式传递文本。
测试数据:
亚达亚达 0.003 40 40.00
yadayada ya 55
yaaaaaaya 100.0000 4
我的正则表达式:
(\w+ *\w* *\w*) (\d*\.*\d*) *(\d*\.*\d*) *(\d*\.*\d*)\n
我得到的群组:
'yada yada','0.003','40','40.00'
'yadayada ya','55',空,空
'yaaaaaaya','100.0000','4',空
但我想要的组是:
'yada yada','0.003','40','40.00'
'yadayada ya',空,空,'55'
'yaaaaaaya',空,'100.0000','4'
是否可以更改正则表达式以将空 (\d*.*\d*) 组引入那些少于 3 个组的行中?这样数字组就是"right-justified"?
我试过添加 ?到前两个 (\d*) 组的末尾,但得到相同的空组。
最简单的方法来执行您通俗地描述为 "right-justifying" 匹配,即。 e.优先匹配后面的可选子表达式,就是把可选成分的"greediness"反转过来。在 Python 正则表达式中,这是通过向每个量化元素添加 ?
来实现的:
(\w+ *\w* *\w*) (\d*?\.*?\d*?) *?(\d*?\.*?\d*?) *?(\d*?\.*?\d*?)\n
请注意,您的表达很自由,不会验证某些格式不正确的输入。如果这对你有用,那很好,否则你可能需要考虑将某些部分放在可选组中,例如 (| \d+(?:\.\d+)?)
以延迟匹配 space 和数字,例如(构造 (|x)
相当于((?:x)??)
).
编辑:正如 Tim 指出的那样,此正则表达式的缺点不仅仅是宽容,而且如果输入的格式稍有不正确,可能会引发灾难性的回溯。如果您打算坚持使用这种方法,我会推荐一些更精确的方法:
(\w+(?: \w+){0,2}) (|\d+(?:\.\d+)?) ?(|\d+(?:\.\d+)?) ?(|\d+(?:\.\d+)?)\n
它仍然可以匹配格式错误的输入,但至少现在更严格了。
您的正则表达式有几个问题,其中之一是 catastrophic backtracking 的高风险,因为正则表达式引擎需要在不匹配的情况下测试的排列数量呈指数级增长。另一个问题是 \w
也会匹配数字,因此第一组可能包含您不希望它包含的数字。
此外,对于这样的 "dynamically growing" 正则表达式,您需要 "match continuation" 功能,例如 \G
或 \K
锚点,但 Python 确实需要不支持那些。
最好的方法是将字符串 .split()
转换为子字符串,然后检查每个子字符串是否包含数字(例如通过 try
ing 将其转换为 float
) 并据此行事。
额外的好处:你有一个可读的Python脚本而不是一个非常复杂的正则表达式。