在python中解析/搜索逗号和分号分隔的字符串
我在ATM上工作的东西有一个(有点)长的数据字符串,如下所示: 56,1,0153,0,0;56,1,0,153,0,0;56,1,0,153,0,0;5,1,2,34,B_3,u 1,0;5,1,2,34,C9841,0 我想查找以“C_3;”开头的值,然后返回后面的数字。我知道它们将始终位于分号分隔的值列表的第四位 我曾考虑使用正则表达式将字符串解析为一个列表并搜索所述列表,但我认为这不是很有效 有人能给我指出解决这个问题的正确方向吗?这个在python中解析/搜索逗号和分号分隔的字符串,python,Python,我在ATM上工作的东西有一个(有点)长的数据字符串,如下所示: 56,1,0153,0,0;56,1,0,153,0,0;56,1,0,153,0,0;5,1,2,34,B_3,u 1,0;5,1,2,34,C9841,0 我想查找以“C_3;”开头的值,然后返回后面的数字。我知道它们将始终位于分号分隔的值列表的第四位 我曾考虑使用正则表达式将字符串解析为一个列表并搜索所述列表,但我认为这不是很有效 有人能给我指出解决这个问题的正确方向吗?这个 import re long_str = "56
import re
long_str = "56,1,0,153,0,0;56,1,0,153,0,0;56,1,0,153,0,0;5,1,2,34,B_3_1_1,0;5,1,2,34,C_9841,0;"
splitted_str = re.split(';|,', long_str)
print next(int(x[2:]) for x in splitted_str if x[:2] == "C_")
替代方案
long_str = "56,1,0,153,0,0;56,1,0,153,0,0;56,1,0,153,0,0;5,1,2,34,B_3_1_1,0;5,1,2,34,C_9841,0;"
split1 = long_str.split(';')
split2 = next(y for y in split1 if "C" in y)
print next(int(x[2:]) for x in split2.split(',') if x[:2] == "C_")
一个简单的解决方案是使用
.find
方法
instr = "56,1,0,153,0,0;56,1,0,153,0,0;56,1,0,153,0,0;5,1,2,34,B_3_1_1,0;5,1,2,34,C_9841,0;"
results = []
index = instr.find('C_')
while index >= 0:
length = instr[index:].find(',')
assert length > 0
results.append(instr[index+2:index+length])
instr = instr[index+length:]
index = instr.find('C_')
另一种简单且可能更有效的方法是在“C_3;”上进行.split
:
您可以使用simple
re.findall()
进行以下操作:
import re
your_string = "56,1,0,153,0,0;56,1,0,153,0,0;56,1,0,153,0,0;5,1,2,34,B_3_1_1,0;5,1,2,34,C_9841,0;"
c_values = re.findall(r"C_(\d+)", your_string) # ['9841']
编辑:如果需要将值作为数字,可以将其转换为生成器:
c_values = [int(x) for x in re.findall(r"C_(\d+)", your_string)] # [9841]
编辑#2:因为您似乎担心性能,几乎在所有情况下,正则表达式都是最快的方法。如果您计划在大量字符串(而不是几个大字符串)上运行此命令,那么每一点都可能有帮助,因此请先编译正则表达式,然后在需要时调用它:
your_regex = re.compile(r"C_(\d+)")
# now use your_regex whenever you need it
c_values = your_regex.findall(your_string) # ['9841']
假设:
s = '56,1,0,153,0,0;56,1,0,153,0,0;56,1,0,153,0,0;5,1,2,34,B_3_1_1,0;5,1,2,34,C_9841,0;'
对于避免使用正则表达式的一个班轮,这应该起作用:
Python 2/3——
Python 3
import itertools # err... it becomes 3 lines
next(i for i in itertools.chain.from_iterable(
ss.split(',') for ss in s.split(';')) if i.startswith('C_'))[2:]
然而,如果事情变得复杂,我自己更喜欢正则表达式。现代规则规定“不要过早优化”和“让你的代码可读”在
C
后面的数字是否加逗号?你说的“永远站在第四位”是什么意思?是的,如果字符串涉及复杂的规则,正则表达式很可能是搜索字符串的最有效方法-您不需要将所有内容拉入/拆分为一个列表。有5个值的逗号分隔字符串:56,1,0153,0,0这些逗号分隔的字符串由分号分隔。这些字符串可以出现在字符串中的任何其他位置吗?至于值本身,假设上面的字符串,您希望结果是9841
,对吗?没错,我希望结果是'9841'(一个字符串)。将有多个C_实例。在这样的字符串中,我需要找到所有实例并将它们存储在一个列表中。您需要确保在'C_9841'
之后有一个,'
。这太低效了。
next(i for sublist in (ss.split(',') for ss in s.split(';')) for i in sublist if i.startswith('C_'))[2:]
import itertools # err... it becomes 3 lines
next(i for i in itertools.chain.from_iterable(
ss.split(',') for ss in s.split(';')) if i.startswith('C_'))[2:]