'Piping'正则表达式操作



在将一些字符串传递给模型之前,我正在尝试使用大量regex操作来清理它们。以前,我在数据帧级别工作,可以使用panda的apply函数来伪管道化我的regex操作:

# take out website prefixes (e.g. www) and suffixes (e.g. .com, .de, .it)
test['shopname'] = test.shopname.apply(lambda x: x if re.match(r'(.*(?<!-))(www).(.*)',x) is None else re.match(r'(.*(?<!-))(www).(.*)',x).group(3).strip()).apply(lambda x: x if re.match(r'(.*).(?=bcomb|bdeb|bitb|bco.ukb|beub|blvb).*$',x) is None else re.match(r'(.*).(?=bcomb|bdeb|bitb|bco.ukb|beub|blvb).*$',x).group(1).strip()) 

然而,现在我正试图编写一个行级函数,该函数可以用apply调用,即

test['identified_name'] = test.apply(lambda row: shop_name_cleaning(row['shopname']), axis=1)

我不知道如何为后续的regex操作"管道"我的字符串了。如果模式不匹配,我的主要困难是让代码返回原始字符串,以便将其传递给下一个regex操作。

我试过了:

def shop_name_cleaning(shop_name):
clean_name = str(re.sub(r'(.*(?<!-))(www).(.*)',x), r'3', trunc_de043)).str(re.sub(r'(.*).(?=bcomb|bdeb|bitb|bco.ukb|beub|blvb).*$', r'1', trunc_de043))
return clean_name

但Python说:

AttributeError: 'str' object has no attribute 'str'

我也试过:

def shop_name_cleaning(shop_name):
clean_name = str(re.match(r'(.*(?<!-))(www).(.*)', trunc_de043).group(3).strip() or trunc_de043).str(re.match(r'(.*).(?=bcomb|bdeb|bitb|bco.ukb|beub|blvb).*$', trunc_de043).group(1).strip() or trunc_de043)
return clean_name

但CCD_ 3不起作用。

我至少有10个正则表达式操作。我正在寻找一种解决方案,它不需要我编写数量惊人的if/else语句(因为如果不匹配,我希望返回原始字符串(。

您的实际错误来自,因为您有str(..).str(...),而没有"someting".str(...)函数。

但是,您忽略了match可以返回None这一事实。你必须检查match是否真的返回了一些东西,如果没有返回原始

def shop_name_cleaning(shop_name):
match = re.match(r'(.*(?<!-))(www).(.*)', shop_name)
shop_name = match.group(3).strip() if match else shop_name
match = re.match(r'(.*).(?=bcomb|bdeb|bitb|bco.ukb|beub|blvb).*$', shop_name)
shop_name = match.group(1).strip() if match else shop_name
return shop_name

如果正则表达式太多,可以创建一个helper函数并进行reduce,但必须确保所有结果组都可以以相同的方式寻址,例如命名:

from functools import reduce
def clean_name(name, regex):
match = re.match(regex, name)
return match.group("out").strip() if match else name

# Or in 3.8+
return match.group("out").strip() if match:=re.match(regex, name) else name

regexes = [
r'(.*(?<!-))(www).(?P<out>.*)',
r'(?P<out>.*).(?=bcomb|bdeb|bitb|bco.ukb|beub|blvb).*$',
]
reduce(clean_name, regexes, shop_name)

这行得通吗?

import re
patterns_and_group_numbers = (
(r'(.*(?<!-))(www).(.*)', 3),
(r'(.*).(?=bcomb|bdeb|bitb|bco.ukb|beub|blvb).*$', 1)
)
regexes_and_group_numbers = [(re.compile(pat), group_no) for (pat, group_no) in patterns_and_group_numbers]
def piped_regexes(string):
for regex, group_no in regexes_and_group_numbers:
if (m := regex.match(string)):
string = m.group(group_no).strip()
return string

以下是我如何解决这个问题:

import re
def shop_name_cleaning(shop_name):
expressions = [r'(?:.*(?<!-))(?:www).(.*)',
r'(.*).(?=bcomb|bdeb|bitb|bco.ukb|beub|blvb).*$']

for expression in expressions:
match = re.match(expression, shop_name)
if match:
return match.group(1).strip()

return shop_name

只需在expressions中列出所有可能的表达式,并确保您感兴趣的子字符串始终位于同一个捕获组(第一、第二、第三、任何(中,并使其他组都不捕获((?:...)(。第一个匹配中断循环并返回所需的子字符串
如果所有表达式都失败,则返回原始shop_name


如果你真的关心哪个表达式匹配(不知道为什么,但可能你需要它(,请使用字典:

def shop_name_cleaning(shop_name):
expressions = {"some_fancy_expression": r'(?:.*(?<!-))(?:www).(.*)',
"some_other_real_cool_expression": r'(.*).(?=bcomb|bdeb|bitb|bco.ukb|beub|blvb).*$'}
for key, expression in expressions.items():
match = re.match(expression, shop_name)
if match:
return key, match.group(1).strip()
return shop_name

最新更新