如何在python中正确地匹配下面的字符串?

2024-05-12 23:52:10 发布

您现在位置:Python中文网/ 问答频道 /正文

我有以下字符串:

1-小胡萝卜(4Kids)(3美元)[额外0计数];[需要5计数]

我正在尝试获得以下组:

Item - 1
Food - Baby Carrots (4Kids) (3 DOLLARS)
Cost - 3
Extra - 0
required - 5

以下是我当前没有拾取任何内容的匹配字符串:

'(?P<item>.+?)\-(?P<food>.*)\[.*?(?P<extra>\d+(\.\d+)?).*\].*\[.*?(?P<required>\d+(\.\d+)?).*\]'

我的尝试有什么问题?你知道吗


Tags: 字符串内容foodrequireditemextrababy计数
3条回答

你原来的正则表达式:

(?P<item>.+?)\-(?P<food>.*)\[.*?(?P<extra>\d+(\.\d+)?).*\].*\[.*?(?P<required>\d+(\.\d+)?).*\]

Regular expression visualization

Debuggex Demo

您的问题主要是由于您搜索的是任何字符,而不是特定字符(数字和静态字符串)。例如:你为什么使用

(?P<item>.+?)

如果只是数字?把它改成

(?P<item>[0-9]+?)

在这种情况下,'+?':reluctant operator是不必要的,因为您总是想要整数。也就是说,匹配的下一部分将不在该数字的中间。你知道吗

此外,这应该锚定到line (input) start

^(?P<item>[0-9]+?)

你不需要escape破折号(尽管它不疼)。你知道吗

^(?P<item>[0-9]+?)-

你的食物组是最复杂的部分

(?P<food>.*)

它不仅仅包含任何字符。根据您的演示输入,它只有字母、空格、数字和paren。所以只需搜索它们:

(?P<food>[\w0-9 ()]+)

以下是我们目前的情况:

^(?P<item>[0-9]+?)- (?P<food>[\w0-9 ()]+)

Regular expression visualization

Debuggex Demo

您将看到这也与成本部分相匹配(您的正则表达式中完全缺少了成本部分…我想这只是一个疏忽)。你知道吗

所以加上成本

  • (
  • 一个数字
  • [space]DOLLARS)

但只有capture数字:

^(?P<item>[0-9]+?)- (?P<food>[\w0-9 ()]+) \((?P<cost>[0-9]+) DOLLARS\)

实际上,剩下的正则表达式工作正常,可以按原样添加到末尾:

\[.*?(?P<extra>\d+(\.\d+)?).*\].*\[.*?(?P<required>\d+(\.\d+)?).*\]

但是,我建议将.*?改为EXTRA[space],如果确实总是在那里找到文本的话(同样,在这种情况下也不需要勉强)。与[space]COUNT;REQUIRED[space]相同。你越是缩小范围,你的正则表达式就越容易调试假设你的输入确实受到限制。你知道吗

以下是最终版本(还有一个线端锚):

^(?P<item>[0-9]+?)- (?P<food>[\w0-9 ()]+) \((?P<cost>[0-9]+) DOLLARS\) \[EXTRA (?P<extra>\d+(\.\d+)?) COUNT\]; \[REQUIRED (?P<required>\d+(\.\d+)?) COUNT\]$

Regular expression visualization

Debuggex Demo


在分析正则表达式之前,我想到的是:

(?P<item>[0-9]+)- (?P<food>[\w ()]+) \((?P<cost>[0-9]+) DOLLARS\) \[EXTRA (?P<extra>[0-9]+) COUNT\]; \[REQUIRED (?P<required>[0-9]+) COUNT\]

Regular expression visualization

Debuggex Demo


所有这些链接都来自Stack Overflow Regular Expressions FAQ。你知道吗

像这样:

(?P<item>.+?)\-\s(?P<food>.*?\)).*?\((?P<cost>\d)\s\w+\)\s\[.*?(?P<extra>\d+(\.\d+)?).*\].*\[.*?(?P<required>\d+(\.\d+)?).*\]

此处演示:http://regex101.com/r/qD1rL9

如上所述,您缺少一个捕获成本,您还需要使food捕获非贪婪并包含结束参数。我的版本:

(?P<Item>\d)-\s*(?P<Food>.*?\))\s*\((?P<Cost>\d*).*EXTRA\s*(?P<Extra>\d*).*REQUIRED\s*(?P<Required>\d*)

{'Food': 'Baby Carrots (4Kids)', 'Item': '1', 'Required': '5', 'Extra': '0', 'Cost': '3'}

使用http://www.pythonregex.com/似乎要快一点

相关问题 更多 >