当前位置:  开发笔记 > 编程语言 > 正文

如何将字符串拆分为列表?

如何解决《如何将字符串拆分为列表?》经验,为你挑选了6个好方法。

如果我有这个字符串:

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

您可以splitre模块中使用.

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()

处理括号的实施留给读者练习.此示例将在添加之前正确执行乘法.



1> Glyph..:

只是碰巧你想要拆分的令牌已经是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']



2> Readonly..:

您可以splitre模块中使用.

re.split(pattern,string,maxsplit = 0,flags = 0)

按模式的出现拆分字符串.如果在模式中使用捕获括号,则模式中所有组的文本也将作为结果列表的一部分返回.

示例代码:

import re
data = re.split(r'(\D)', '2+24*48/32')

\ d

如果未指定UNICODE标志,则\ D匹配任何非数字字符; 这相当于集[^ 0-9].



3> Jerub..:

这看起来像解析问题,因此我不得不提出基于解析技术的解决方案.

虽然看起来你想要"拆分"这个字符串,但我认为你真正想做的就是"标记"它.标记化或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()

处理括号的实施留给读者练习.此示例将在添加之前正确执行乘法.



4> molasses..:
>>> 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']



5> Ber..:

这是一个解析问题,因此正则表达式和split()都不是"好"的解决方案.请改用解析器生成器.

我会密切关注pyparsing.在Python杂志中也有一些关于pyparsing的体面文章.



6> Jiayao Yu..:

s ="2 + 24*48/32"

p = re.compile(r'(\ W +)')

p.split(S)

推荐阅读
夏晶阳--艺术
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有