如果我有这个字符串:
2 + 24*32分之48
创建此列表的最有效方法是什么:
['2','+','24','*','48','/','32']
Glyph.. 50
只是碰巧你想要拆分的令牌已经是Python令牌,所以你可以使用内置tokenize
模块.它几乎是一个单行:
from cStringIO import StringIO from tokenize import generate_tokens STRING = 1 list(token[STRING] for token in generate_tokens(StringIO('2+24*48/32').readline) if token[STRING]) ['2', '+', '24', '*', '48', '/', '32']
Readonly.. 36
您可以split
从re
模块中使用.
re.split(pattern,string,maxsplit = 0,flags = 0)
按模式的出现拆分字符串.如果在模式中使用捕获括号,则模式中所有组的文本也将作为结果列表的一部分返回.
示例代码:
import re data = re.split(r'(\D)', '2+24*48/32')
\ d
如果未指定UNICODE标志,则\ D匹配任何非数字字符; 这相当于集[^ 0-9].
Jerub.. 18
这看起来像解析问题,因此我不得不提出基于解析技术的解决方案.
虽然看起来你想要"拆分"这个字符串,但我认为你真正想做的就是"标记"它.标记化或lexxing是解析之前的编译步骤.我在编辑中修改了我的原始示例,以在此处实现正确的递归正确解析器.这是手动实现解析器的最简单方法.
import re patterns = [ ('number', re.compile('\d+')), ('*', re.compile(r'\*')), ('/', re.compile(r'\/')), ('+', re.compile(r'\+')), ('-', re.compile(r'\-')), ] whitespace = re.compile('\W+') def tokenize(string): while string: # strip off whitespace m = whitespace.match(string) if m: string = string[m.end():] for tokentype, pattern in patterns: m = pattern.match(string) if m: yield tokentype, m.group(0) string = string[m.end():] def parseNumber(tokens): tokentype, literal = tokens.pop(0) assert tokentype == 'number' return int(literal) def parseMultiplication(tokens): product = parseNumber(tokens) while tokens and tokens[0][0] in ('*', '/'): tokentype, literal = tokens.pop(0) if tokentype == '*': product *= parseNumber(tokens) elif tokentype == '/': product /= parseNumber(tokens) else: raise ValueError("Parse Error, unexpected %s %s" % (tokentype, literal)) return product def parseAddition(tokens): total = parseMultiplication(tokens) while tokens and tokens[0][0] in ('+', '-'): tokentype, literal = tokens.pop(0) if tokentype == '+': total += parseMultiplication(tokens) elif tokentype == '-': total -= parseMultiplication(tokens) else: raise ValueError("Parse Error, unexpected %s %s" % (tokentype, literal)) return total def parse(tokens): tokenlist = list(tokens) returnvalue = parseAddition(tokenlist) if tokenlist: print 'Unconsumed data', tokenlist return returnvalue def main(): string = '2+24*48/32' for tokentype, literal in tokenize(string): print tokentype, literal print parse(tokenize(string)) if __name__ == '__main__': main()
处理括号的实施留给读者练习.此示例将在添加之前正确执行乘法.
只是碰巧你想要拆分的令牌已经是Python令牌,所以你可以使用内置tokenize
模块.它几乎是一个单行:
from cStringIO import StringIO from tokenize import generate_tokens STRING = 1 list(token[STRING] for token in generate_tokens(StringIO('2+24*48/32').readline) if token[STRING]) ['2', '+', '24', '*', '48', '/', '32']
您可以split
从re
模块中使用.
re.split(pattern,string,maxsplit = 0,flags = 0)
按模式的出现拆分字符串.如果在模式中使用捕获括号,则模式中所有组的文本也将作为结果列表的一部分返回.
示例代码:
import re data = re.split(r'(\D)', '2+24*48/32')
\ d
如果未指定UNICODE标志,则\ D匹配任何非数字字符; 这相当于集[^ 0-9].
这看起来像解析问题,因此我不得不提出基于解析技术的解决方案.
虽然看起来你想要"拆分"这个字符串,但我认为你真正想做的就是"标记"它.标记化或lexxing是解析之前的编译步骤.我在编辑中修改了我的原始示例,以在此处实现正确的递归正确解析器.这是手动实现解析器的最简单方法.
import re patterns = [ ('number', re.compile('\d+')), ('*', re.compile(r'\*')), ('/', re.compile(r'\/')), ('+', re.compile(r'\+')), ('-', re.compile(r'\-')), ] whitespace = re.compile('\W+') def tokenize(string): while string: # strip off whitespace m = whitespace.match(string) if m: string = string[m.end():] for tokentype, pattern in patterns: m = pattern.match(string) if m: yield tokentype, m.group(0) string = string[m.end():] def parseNumber(tokens): tokentype, literal = tokens.pop(0) assert tokentype == 'number' return int(literal) def parseMultiplication(tokens): product = parseNumber(tokens) while tokens and tokens[0][0] in ('*', '/'): tokentype, literal = tokens.pop(0) if tokentype == '*': product *= parseNumber(tokens) elif tokentype == '/': product /= parseNumber(tokens) else: raise ValueError("Parse Error, unexpected %s %s" % (tokentype, literal)) return product def parseAddition(tokens): total = parseMultiplication(tokens) while tokens and tokens[0][0] in ('+', '-'): tokentype, literal = tokens.pop(0) if tokentype == '+': total += parseMultiplication(tokens) elif tokentype == '-': total -= parseMultiplication(tokens) else: raise ValueError("Parse Error, unexpected %s %s" % (tokentype, literal)) return total def parse(tokens): tokenlist = list(tokens) returnvalue = parseAddition(tokenlist) if tokenlist: print 'Unconsumed data', tokenlist return returnvalue def main(): string = '2+24*48/32' for tokentype, literal in tokenize(string): print tokentype, literal print parse(tokenize(string)) if __name__ == '__main__': main()
处理括号的实施留给读者练习.此示例将在添加之前正确执行乘法.
>>> import re >>> re.findall(r'\d+|\D+', '2+24*48/32=10') ['2', '+', '24', '*', '48', '/', '32', '=', '10']
匹配连续数字或连续的非数字.
每个匹配都作为列表中的新元素返回.
根据用途,您可能需要更改正则表达式.例如,如果您需要匹配小数点的数字.
>>> re.findall(r'[0-9\.]+|[^0-9\.]+', '2+24*48/32=10.1') ['2', '+', '24', '*', '48', '/', '32', '=', '10.1']
这是一个解析问题,因此正则表达式和split()都不是"好"的解决方案.请改用解析器生成器.
我会密切关注pyparsing.在Python杂志中也有一些关于pyparsing的体面文章.
s ="2 + 24*48/32"
p = re.compile(r'(\ W +)')
p.split(S)