正则表达式提取任意数量的子模式
Regex extract arbitrary number of subpatterns
我的句子结构为“名称有数字 1 字 1、数字 2 字 2、... 和数字 N 字 N”,其中子模式“数字字”的数量因句子而异,因此是不确定的。最后一个子模式前有一个“and”。例如“爱丽丝有 1 个苹果、2 个香蕉、....和 6 个橙子。”
如何在 python 中使用正则表达式提取这些数字和单词?我希望输出如下:
姓名,
Digit
Word
digit1
word1
digit2
word2
...
...
digitN
wordN
我试过以下方法:
s = 'Alice has 1 apple, 2 bananas, and 3 oranges.'
import re
matches = re.finditer(r'([Aa-z]+) has (\d) ([a-z]+)( and)*', s)
for match in matches:
print(match.groups())
但这只给我 ('Alice', '1', 'apple', None), 缺少 '2', 'bananas', '3', 'oranges'.
如果你想在一个正则表达式中匹配所有内容,你需要这样的东西:
([^\s]+) has (?:(?:,\s+)?(?:and\s+)?(\d+)\s+([^\s,]+)){1,}
但是,我不确定 python 是否可以处理重复组。至少,我还没有找到从 python 对象中提取重复组的方法。
下面是我建议的解决问题的方法:
import re
s = 'Alice has 1 apple, 2 bananas, and 3 oranges.'
matches = re.match(r'^([^\s]+)', s)
print(f'Name: {matches.group(0)}')
matches = re.findall(r'(?:(?:,\s+)?(?:and\s+)?(\d+)\s+([^\s,]+))', s)
for match in matches:
print(f'{match[0]} - {match[1]}')
示例输出
Name: Alice
1 - apple
2 - bananas
3 - oranges.
Process finished with exit code 0
正则表达式解释
^([^\s]+)
- 有几种不同的方法可以解决这个问题,但它只是抓住所有内容,直到字符串中的第一个 space。
(?: - Non-capturing group
(?:,\s+)? - Optionally allow the string to have a `,` followed by spaces
(?:and\s+)? - Optionally allow the string to contain the word `and` followed by spaces
(\d+) - Must have a number
\s+ - Spaces between number and description
([^\s,]+) - Grab the next set of characters and stop when you find a space or comma. This should be the word (e.g. apple)
)
这第二个正则表达式只是确保您可以提取各种形式的 1 apple
。所以它基本上会匹配以下模式:
1 apple
, 1 apple
, and 1 apple
and 1 apple
作为旁注,解析器更适合解决 long-运行 中的这些问题。句子中出现更多差异,使用简单的正则表达式开始变得非常难以解析。
使用PyPi regex.
import regex
s = 'Alice has 1 apple, 2 bananas, and 3 oranges.'
matches = regex.finditer(r'(?P<word1>[A-Za-z]+) has(?:(?:\s+|,\s+|,?\s+and\s+)?(?P<number>\d+)\s+(?P<word2>[a-z]+))*', s)
for match in matches:
print(match.capturesdict())
结果:{'word1': ['Alice'], 'number': ['1', '2', '3'], 'word2': ['apple', 'bananas', 'oranges']}
我的句子结构为“名称有数字 1 字 1、数字 2 字 2、... 和数字 N 字 N”,其中子模式“数字字”的数量因句子而异,因此是不确定的。最后一个子模式前有一个“and”。例如“爱丽丝有 1 个苹果、2 个香蕉、....和 6 个橙子。”
如何在 python 中使用正则表达式提取这些数字和单词?我希望输出如下:
姓名,
Digit | Word |
---|---|
digit1 | word1 |
digit2 | word2 |
... | ... |
digitN | wordN |
我试过以下方法:
s = 'Alice has 1 apple, 2 bananas, and 3 oranges.'
import re
matches = re.finditer(r'([Aa-z]+) has (\d) ([a-z]+)( and)*', s)
for match in matches:
print(match.groups())
但这只给我 ('Alice', '1', 'apple', None), 缺少 '2', 'bananas', '3', 'oranges'.
如果你想在一个正则表达式中匹配所有内容,你需要这样的东西:
([^\s]+) has (?:(?:,\s+)?(?:and\s+)?(\d+)\s+([^\s,]+)){1,}
但是,我不确定 python 是否可以处理重复组。至少,我还没有找到从 python 对象中提取重复组的方法。
下面是我建议的解决问题的方法:
import re
s = 'Alice has 1 apple, 2 bananas, and 3 oranges.'
matches = re.match(r'^([^\s]+)', s)
print(f'Name: {matches.group(0)}')
matches = re.findall(r'(?:(?:,\s+)?(?:and\s+)?(\d+)\s+([^\s,]+))', s)
for match in matches:
print(f'{match[0]} - {match[1]}')
示例输出
Name: Alice
1 - apple
2 - bananas
3 - oranges.
Process finished with exit code 0
正则表达式解释
^([^\s]+)
- 有几种不同的方法可以解决这个问题,但它只是抓住所有内容,直到字符串中的第一个 space。
(?: - Non-capturing group
(?:,\s+)? - Optionally allow the string to have a `,` followed by spaces
(?:and\s+)? - Optionally allow the string to contain the word `and` followed by spaces
(\d+) - Must have a number
\s+ - Spaces between number and description
([^\s,]+) - Grab the next set of characters and stop when you find a space or comma. This should be the word (e.g. apple)
)
这第二个正则表达式只是确保您可以提取各种形式的 1 apple
。所以它基本上会匹配以下模式:
1 apple
, 1 apple
, and 1 apple
and 1 apple
作为旁注,解析器更适合解决 long-运行 中的这些问题。句子中出现更多差异,使用简单的正则表达式开始变得非常难以解析。
使用PyPi regex.
import regex
s = 'Alice has 1 apple, 2 bananas, and 3 oranges.'
matches = regex.finditer(r'(?P<word1>[A-Za-z]+) has(?:(?:\s+|,\s+|,?\s+and\s+)?(?P<number>\d+)\s+(?P<word2>[a-z]+))*', s)
for match in matches:
print(match.capturesdict())
结果:{'word1': ['Alice'], 'number': ['1', '2', '3'], 'word2': ['apple', 'bananas', 'oranges']}