使用正则表达式的更好方法
Better way to use regular expression
我有一个字符串中有多个帐户的帐户信息字符串(示例显示一行,我实际上有一个包含多行帐户数据的文本文件,所以还有另一个循环遍历字符串中的每一行我的代码中的文本文件)。我需要将每个帐户拉到自己的行中。下面的代码有效,但我认为有更有效或更好的方法来做到这一点。我刚开始学习正则表达式。
import re
import pandas as pd
allAccounts = []
example = '02-0015800-00 NAME1 100 SOME ST Active 3/8/2021 139.23 139.81 0.42 02-0023901-01 NAME2 101 SOME ST Active 3/8/2021 512.33 482.96 -5.73'
rex = '[0-9]{1,2}-[0-9]{1,7}-[0-9]{1,2}'
accounts = re.findall(rex, example)
for account in accounts:
example= example.replace(account, f'||{account}')
example = [account.replace(' ', '|').split('|') for account in example.split('||')][1:]
allAccounts += example
df = pd.DataFrame(allAccounts)
df
从代码的正则表达式部分,我希望它是 return:
['02-0015800-00 NAME1 100 SOME ST Active 3/8/2021 139.23 139.81 0.42', ' 02-0023901-01 NAME2 101 SOME ST Active 3/8/2021 512.33 482.96 -5.73']
# or
'||02-0015800-00 NAME1 100 SOME ST Active 3/8/2021 139.23 139.81 0.42 ||02-0023901-01 NAME2 101 SOME ST Active 3/8/2021 512.33 482.96 -5.73'
代码return是我最终想要的df:
0 1 2 3 4 5 6 7 8
0 02-0015800-00 NAME1 100 SOME ST Active 3/8/2021 139.23 139.81 0.42
1 02-0023901-01 NAME2 101 SOME ST Active 3/8/2021 512.33 482.96 -5.73 None
但我觉得有比我正在做的更好的方法来使用正则表达式。阅读文档似乎 re.sub
应该这样做,但它只是替换它遇到的第一个帐号,它只想替换帐号而不是添加 '||'分隔符到开头。
更新:
使用以下它接近我想要的但不确定为什么列表中的第一项是''。
example = '02-0015800-00 NAME1 100 SOME ST Active 3/8/2021 139.23 139.81 0.42 02-0023901-01 NAME2 101 SOME ST Active 3/8/2021 512.33 482.96 -5.73'
rex = re.compile('(?=[0-9][0-9]-[0-9][0-9][0-9][0-9][0-9][0-9][0-9]-[0-9][0-9])')
re.split(rex, example)
输出:
['',
'02-0015800-00 NAME1 100 SOME ST Active 3/8/2021 139.23 139.81 0.42 ',
'02-0023901-01 NAME2 101 SOME ST Active 3/8/2021 512.33 482.96 -5.73']
不使用拆分,您可以匹配以下值:
\b\d\d-\d{7}-\d\d\b.*?(?=\s*\b\d\d-\d{7}-\d\d\b.*?|$)
说明
\b\d\d-\d{7}-\d\d\b
使用量词匹配 2 位 - 7 位 - 2 位的模式
.*?
尽可能少地匹配任何字符
(?=\s*\b\d\d-\d{7}-\d\d\b.*?|$)
正向先行断言右侧的数字模式或字符串的末尾也匹配最后一次出现
例子
import re
pattern = r"\b\d\d-\d{7}-\d\d\b.*?(?=\s*\b\d\d-\d{7}-\d\d\b.*?|$)"
s = "02-0015800-00 NAME1 100 SOME ST Active 3/8/2021 139.23 139.81 0.42 02-0023901-01 NAME2 101 SOME ST Active 3/8/2021 512.33 482.96 -5.73"
print(re.findall(pattern, s))
输出
['02-0015800-00 NAME1 100 SOME ST Active 3/8/2021 139.23 139.81 0.42', '02-0023901-01 NAME2 101 SOME ST Active 3/8/2021 512.33 482.96 -5.73']
如果必须使用split:
重新导入
pattern = r"\b(?=\d\d-\d{7}-\d\d\b)"
s = "02-0015800-00 NAME1 100 SOME ST Active 3/8/2021 139.23 139.81 0.42 02-0023901-01 NAME2 101 SOME ST Active 3/8/2021 512.33 482.96 -5.73"
result = [m.strip() for m in re.split(pattern, s) if m]
print(result)
看到一个Python demo
我有一个字符串中有多个帐户的帐户信息字符串(示例显示一行,我实际上有一个包含多行帐户数据的文本文件,所以还有另一个循环遍历字符串中的每一行我的代码中的文本文件)。我需要将每个帐户拉到自己的行中。下面的代码有效,但我认为有更有效或更好的方法来做到这一点。我刚开始学习正则表达式。
import re
import pandas as pd
allAccounts = []
example = '02-0015800-00 NAME1 100 SOME ST Active 3/8/2021 139.23 139.81 0.42 02-0023901-01 NAME2 101 SOME ST Active 3/8/2021 512.33 482.96 -5.73'
rex = '[0-9]{1,2}-[0-9]{1,7}-[0-9]{1,2}'
accounts = re.findall(rex, example)
for account in accounts:
example= example.replace(account, f'||{account}')
example = [account.replace(' ', '|').split('|') for account in example.split('||')][1:]
allAccounts += example
df = pd.DataFrame(allAccounts)
df
从代码的正则表达式部分,我希望它是 return:
['02-0015800-00 NAME1 100 SOME ST Active 3/8/2021 139.23 139.81 0.42', ' 02-0023901-01 NAME2 101 SOME ST Active 3/8/2021 512.33 482.96 -5.73']
# or
'||02-0015800-00 NAME1 100 SOME ST Active 3/8/2021 139.23 139.81 0.42 ||02-0023901-01 NAME2 101 SOME ST Active 3/8/2021 512.33 482.96 -5.73'
代码return是我最终想要的df:
0 1 2 3 4 5 6 7 8
0 02-0015800-00 NAME1 100 SOME ST Active 3/8/2021 139.23 139.81 0.42
1 02-0023901-01 NAME2 101 SOME ST Active 3/8/2021 512.33 482.96 -5.73 None
但我觉得有比我正在做的更好的方法来使用正则表达式。阅读文档似乎 re.sub
应该这样做,但它只是替换它遇到的第一个帐号,它只想替换帐号而不是添加 '||'分隔符到开头。
更新:
使用以下它接近我想要的但不确定为什么列表中的第一项是''。
example = '02-0015800-00 NAME1 100 SOME ST Active 3/8/2021 139.23 139.81 0.42 02-0023901-01 NAME2 101 SOME ST Active 3/8/2021 512.33 482.96 -5.73'
rex = re.compile('(?=[0-9][0-9]-[0-9][0-9][0-9][0-9][0-9][0-9][0-9]-[0-9][0-9])')
re.split(rex, example)
输出:
['',
'02-0015800-00 NAME1 100 SOME ST Active 3/8/2021 139.23 139.81 0.42 ',
'02-0023901-01 NAME2 101 SOME ST Active 3/8/2021 512.33 482.96 -5.73']
不使用拆分,您可以匹配以下值:
\b\d\d-\d{7}-\d\d\b.*?(?=\s*\b\d\d-\d{7}-\d\d\b.*?|$)
说明
\b\d\d-\d{7}-\d\d\b
使用量词匹配 2 位 - 7 位 - 2 位的模式.*?
尽可能少地匹配任何字符(?=\s*\b\d\d-\d{7}-\d\d\b.*?|$)
正向先行断言右侧的数字模式或字符串的末尾也匹配最后一次出现
例子
import re
pattern = r"\b\d\d-\d{7}-\d\d\b.*?(?=\s*\b\d\d-\d{7}-\d\d\b.*?|$)"
s = "02-0015800-00 NAME1 100 SOME ST Active 3/8/2021 139.23 139.81 0.42 02-0023901-01 NAME2 101 SOME ST Active 3/8/2021 512.33 482.96 -5.73"
print(re.findall(pattern, s))
输出
['02-0015800-00 NAME1 100 SOME ST Active 3/8/2021 139.23 139.81 0.42', '02-0023901-01 NAME2 101 SOME ST Active 3/8/2021 512.33 482.96 -5.73']
如果必须使用split:
重新导入
pattern = r"\b(?=\d\d-\d{7}-\d\d\b)"
s = "02-0015800-00 NAME1 100 SOME ST Active 3/8/2021 139.23 139.81 0.42 02-0023901-01 NAME2 101 SOME ST Active 3/8/2021 512.33 482.96 -5.73"
result = [m.strip() for m in re.split(pattern, s) if m]
print(result)
看到一个Python demo