繁体   English   中英

如何使用正则表达式将多个单词作为单个条目匹配?

[英]How to match multiple words as a single entry with Regex?

我有一个物品清单,其中还包括物品的类型和重量/尺寸。 我正在尝试提取项目名称。 我尝试了几种不同的方法,但最接近的是将每个单词提取为一个条目。

我使用的正则表达式模式:

pattern_2=re.compile(r'[a-zA-Z]+\s')

我得到这个结果:

list=['Milk ','Loaf ','of ','Fresh ','White ','Bread ','Rice ']

我想要的结果是这样的:

list=['Milk','Loaf of Fresh White Bread']

我尝试了这里提出的模式,但它匹配整个列表作为一个块。 匹配多行文本块的正则表达式

我的清单的一部分:

list=['Milk (regular) (1 gallon)', 'Loaf of Fresh White Bread (1 lb)', 'Rice (white) (1 lb)', 'Eggs (regular) (12)', 'Local Cheese (1 lb)']

列表本身更长,所以我试图找到一种可以用于整个列表的模式。 是否可以编写一个与整个列表项匹配的正则表达式模式?

您可以使用

import re
l=['Milk (regular) (1 gallon)', 'Loaf of Fresh White Bread (1 lb)', 'Rice (white) (1 lb)', 'Eggs (regular) (12)', 'Local Cheese (1 lb)']
for s in l:
    m = re.search(r'^[a-z]+(?:\s+[a-z]+)*', s, re.I)
    if m:
        print(m.group())

或者,如果您使用 Python 3.8+:

import re
l=['Milk (regular) (1 gallon)', 'Loaf of Fresh White Bread (1 lb)', 'Rice (white) (1 lb)', 'Eggs (regular) (12)', 'Local Cheese (1 lb)']
print( [m.group() for s in l if (m := re.search(r'^[a-z]+(?:\s+[a-z]+)*', s, re.I))] )

输出:

Milk
Loaf of Fresh White Bread
Rice
Eggs
Local Cheese

请参阅在线 Python 演示

^[az]+(?:\\s+[az]+)*正则表达式匹配一个或多个字母,然后匹配零次或多次出现在字符串开头的一个或多个字母,由于re.I不区分大小写re.I选择。

我设法到了这里,但在元素的开头/结尾我仍然有空格要删除:

import re

pattern_2=re.compile(r'([a-zA-Z\s]+\s)')

lst = ['Milk (regular) (1 gallon)', 'Loaf of Fresh White Bread (1 lb)', 'Rice (white) (1 lb)', 'Eggs (regular) (12)', 'Local Cheese (1 lb)']
string = "Milk (regular) (1 gallon), Loaf of Fresh White Bread (1 lb), Rice (white) (1 lb), Eggs (regular) (12), Local Cheese (1 lb)"

# for a string
result_string = pattern_2.findall(string)
print(result_string)
# for a list
result_lst = pattern_2.findall(', '.join(lst))
print(result_lst)

''' OUTPUT
['Milk ', ' Loaf of Fresh White Bread ', ' Rice ', ' Eggs ', ' Local Cheese ']
['Milk ', ' Loaf of Fresh White Bread ', ' Rice ', ' Eggs ', ' Local Cheese ']
'''
import re

s = re.findall(r'[^()]+', 'Loaf of Fresh White Bread (1 lb)')[0].rstrip()

要将其应用于整个列表,请使用以下代码。 (given_list->result_list)

import re

given_list = ['Milk (regular) (1 gallon)', 'Loaf of Fresh White Bread (1 lb)', 'Rice (white) (1 lb)', 'Eggs (regular) (12)', 'Local Cheese (1 lb)']
result_list = [re.findall(r'[^()]+', x)[0].rstrip() for x in given_list]
print(result_list) 
# prints ['Milk', 'Loaf of Fresh White Bread', 'Rice', 'Eggs', 'Local Cheese']

使用正则表达式非常棘手。

我建议您查看正则表达式自动机理论以熟悉此工具。

代码说明:

r' [^()]+ ' 可以分解为[]+^()

' [] ' 是一组标记(字母)。

我们在[] 中定义了一些标记集。

' + ' 表示迭代至少 1 次。

' []+ ' 表示某组标记已被迭代 1 次或多次

' ^ ' 表示补集

简单来说,它的意思是“除了某物之外的所有东西的集合”

这里的“东西”是' ',和' '。

所以“除了括号之外的所有东西”都被设置了。

并且该集合的迭代次数超过 1 次。

所以在人类语言中,这意味着

"除了 '(' 或 ')' 之外的任何字符的字符串,长度为 1 或更多。"

findall方法查找满足此条件的所有子字符串,

列出它。

[0]返回它的第一个元素

rstrip删除尾随空格,因为我们无法使用正则表达式删除它。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM