2017-02-20 45 views
1

搜索一个逗号和分号分隔的字符串,我在ATM上工作的事情有一个(有点)数据的长字符串是这样的:解析/ Python中

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_'开头的值并返回它后面的数字。我知道他们将始终处于以分号分隔的值列表中的第四位。

我正在考虑使用正则表达式来解析字符串到列表中,并搜索列表,但不认为这将是非常有效的。

有人可以指出我在正确的方向来解决这个问题吗?

+1

“C_”后面加逗号或不加逗号的数字? “总是处于第四位”是什么意思?是的,如果涉及复杂的规则,正则表达式最有可能是搜索字符串的最有效方式 - 您只需将所有内容拉到/分割成列表即可。 – zwer

+0

有5个逗号分隔的字符串:56,1,0,153,0,0 这些逗号分隔的字符串之间用分号隔开 –

+0

C_'可以出现在字符串的其他位置吗?至于价值本身,假设上面的字符串,你想'9841'作为结果,对吧? – zwer

回答

2

您可以使用简单的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'] 
0

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_") 
+0

这是**疯狂**效率低下。 – zwer

0

一个简单的解决方案是使用该方法.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_') 

另一种简单的,可能更有效的方法将是.split的 “C_”:

bits = instr.split('C_')[1:] 
stops = [bit.find(',') for bit in bits] 
results = [bit[2:stop] for bit, stop in zip(bits, stops) if stop > 0] 
+0

你需要确定在'C_9841'后有'',''。 – Elmex80s

+0

@ Elmex80s我假设从这个例子来看,但你是对的,而不是马虎。 –

0

假设:

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/3credit

next(i for sublist in (ss.split(',') for ss in s.split(';')) for i in sublist if i.startswith('C_'))[2:] 

的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:] 

然而,如果事情变得复杂,我自己比较喜欢正则表达式。 现代规则规定“不要做过早的优化”和“让你的代码易读”。