Python 正则表达式分隔以括号中的数字结尾的字符串
Python regex to separate strings which ends with numbers in parenthesis
我有一个在 beautifulsoup 操作后生成的列表。它的字符串由括号中的数字分隔,我想将其拆分为内部列表。例如我有
L1=['alpha(1) beta(4)','delta(5) gamma(6)']
这需要转换为
[[‘alpha’, ‘beta’],[‘gamma’, ‘delta’]]
我从这个开始
[re.split(r'\(\d\)',item) for item in L1]
但这会在最后一项中创建额外的 space,然后在最后生成一个白色的 space 项。
[['alpha', ' beta', ''], ['delta', ' gamma', '']]
所以我像这样在代码中添加一行
L1=[re.split(r'\(\d\)',item) for item in L1]
[[x.strip() for x in y if x] for y in L1]
这就是我想要的
[['alpha', 'beta'], ['delta', 'gamma']]
所以我的查询是
- 为什么它只使用命令的第一行来完成它所做的事情。为什么创建最后一个元素。
- 是否有更好的方法通过单一且更简单的正则表达式实现此目的?
我会使用拆分:
print([[j.split("(")[0] for j in i.split()] for i in L1])
Returns:
[['alpha', 'beta'], ['delta', 'gamma']]
以逗号分隔,然后使用正则表达式替换方括号和数字。最后将字符串拆分为空格。
import re
>>> [re.sub('\(\d\)', '', y).split() for x in L1 for y in x.split(',')]
[['alpha', 'beta'], ['delta', 'gamma']]
根据文档,re.split()
的行为与 str.split()
相同,str.split()
的文档明确说明
Splitting an empty string with a specified separator returns [''].
由于分隔符右侧有一个空字符串,因此您在 split()
结果中得到一个空字符串。我认为为空字符串返回 ''
的想法会导致更一致和可预测的行为。
关于更好的代码实现方式,我觉得下面的比较清楚:
>>> L1=['alpha(1) beta(4)','delta(5) gamma(6)']
>>> name_list = []
>>> for s in L1:
name_list.append(re.findall(r'(\w+)\(\d+\)', s))
>>> name_list
[['alpha', 'beta'], ['delta', 'gamma']]
或使用列表理解:
name_list = [re.findall(r'(\w+)\(\d+\)', s) for s in L1]
\(\d\)
模式在您的字符串中找到多个非重叠匹配项并在这些位置拆分字符串。这意味着它将 'alpha(1) beta(4)'
拆分为 alpha
、 beta
和一个空字符串,因为最后一个 (4)
位于 beta
和字符串末尾之间。
如果您想使用原始 re.split
方法的正则表达式,您可以考虑使用 filter
去除结果列表中的空项:
import re
L1=['alpha(1) beta(4)','delta(5) gamma(6)']
res = [filter(None, re.split(r'\(\d+\)\s*', item)) for item in L1]
print(res)
# => [['alpha', 'beta'], ['delta', 'gamma']]
见Python demo。 \(\d+\)\s*
将匹配括号内的数字,\s*
将匹配 0+ 个空格。
我有一个在 beautifulsoup 操作后生成的列表。它的字符串由括号中的数字分隔,我想将其拆分为内部列表。例如我有
L1=['alpha(1) beta(4)','delta(5) gamma(6)']
这需要转换为
[[‘alpha’, ‘beta’],[‘gamma’, ‘delta’]]
我从这个开始
[re.split(r'\(\d\)',item) for item in L1]
但这会在最后一项中创建额外的 space,然后在最后生成一个白色的 space 项。
[['alpha', ' beta', ''], ['delta', ' gamma', '']]
所以我像这样在代码中添加一行
L1=[re.split(r'\(\d\)',item) for item in L1]
[[x.strip() for x in y if x] for y in L1]
这就是我想要的
[['alpha', 'beta'], ['delta', 'gamma']]
所以我的查询是
- 为什么它只使用命令的第一行来完成它所做的事情。为什么创建最后一个元素。
- 是否有更好的方法通过单一且更简单的正则表达式实现此目的?
我会使用拆分:
print([[j.split("(")[0] for j in i.split()] for i in L1])
Returns:
[['alpha', 'beta'], ['delta', 'gamma']]
以逗号分隔,然后使用正则表达式替换方括号和数字。最后将字符串拆分为空格。
import re
>>> [re.sub('\(\d\)', '', y).split() for x in L1 for y in x.split(',')]
[['alpha', 'beta'], ['delta', 'gamma']]
根据文档,re.split()
的行为与 str.split()
相同,str.split()
的文档明确说明
Splitting an empty string with a specified separator returns [''].
由于分隔符右侧有一个空字符串,因此您在 split()
结果中得到一个空字符串。我认为为空字符串返回 ''
的想法会导致更一致和可预测的行为。
关于更好的代码实现方式,我觉得下面的比较清楚:
>>> L1=['alpha(1) beta(4)','delta(5) gamma(6)']
>>> name_list = []
>>> for s in L1:
name_list.append(re.findall(r'(\w+)\(\d+\)', s))
>>> name_list
[['alpha', 'beta'], ['delta', 'gamma']]
或使用列表理解:
name_list = [re.findall(r'(\w+)\(\d+\)', s) for s in L1]
\(\d\)
模式在您的字符串中找到多个非重叠匹配项并在这些位置拆分字符串。这意味着它将 'alpha(1) beta(4)'
拆分为 alpha
、 beta
和一个空字符串,因为最后一个 (4)
位于 beta
和字符串末尾之间。
如果您想使用原始 re.split
方法的正则表达式,您可以考虑使用 filter
去除结果列表中的空项:
import re
L1=['alpha(1) beta(4)','delta(5) gamma(6)']
res = [filter(None, re.split(r'\(\d+\)\s*', item)) for item in L1]
print(res)
# => [['alpha', 'beta'], ['delta', 'gamma']]
见Python demo。 \(\d+\)\s*
将匹配括号内的数字,\s*
将匹配 0+ 个空格。