使用正则表达式在Python中分割字符串

9
我将使用Python的partition和正则表达式来清理文本字符串。举个例子:
testString = 'Tre Bröders Väg 6 2tr'
sep = '[0-9]tr'
head,sep,tail = testString.partition(sep)
head
>>>'Tre Br\xc3\xb6ders V\xc3\xa4g 6 2tr'

头部仍然包含我想要删除的2tr。我不太擅长正则表达式,但是[0-9]不应该行吗?

我期望从这个例子中得到的输出是

head
>>> 'Tre Br\xc3\xb6ders V\xc3\xa4g 6

你期望得到什么输出? - Anand S Kumar
你甚至没有使用正则表达式,为什么[0-9]会奏效呢? - Ashwini Chaudhary
添加了我期望的输出 - seb
@AshwiniChaudhary,为什么我没有使用正则表达式?是否需要特别添加一些内容? 我正在使用这份备忘单:http://www.cheatography.com/davechild/cheat-sheets/regular-expressions/ - seb
你只需要头部吗? - Anand S Kumar
嗯,我只想要头部。 - seb
4个回答

6

普通的re.split()方法

您可以使用re.split()来提取head

import re

testString = 'Tre Bröders Väg 6 2tr'
sep = r'[0-9]tr'  # "r" is essential here!
head, tail = re.split(sep, testString)  
head.strip()
>>>'Tre Bröders Väg 6'

巧克力撒在re.split()方法上

如果您用() 捕获 sep,那么re.split()表现得像一个伪re.partition()(实际上Python中没有这种方法...)

import re

testString = 'Tre Bröders Väg 6 2tr'
sep = r'([0-9]tr)'  # "()" added.
# maxplit of 1 is added at the suggestion of Ángel ;)
head, sep, tail = re.split(sep, testString, 1)
head, sep, tail
>>>('Tre Bröders Väg 6 ', '2tr', '')

一个包含组的re.split确实是创建正则表达式分区的方法,尽管为了实际模拟分区,您应该添加一个最大分割数为1,即re.split(sep, testString, 1) - Ángel
非常感谢你,Ángel。现在看起来更漂亮了! - yeiichi

5

str.partition不支持正则表达式,因此当您给它一个字符串,例如-'[0-9]tr',它会尝试在testString中查找该确切字符串以进行分区,而不使用任何正则表达式。

根据str.partition的文档-

在第一次出现sep的位置拆分字符串,并返回一个包含分隔符前面部分、分隔符本身和分隔符后面部分的3元组。如果未找到分隔符,则返回一个包含字符串本身、两个空字符串的3元组。

既然您说只想要head,您可以使用re.split()方法来自re模块,将maxsplit设置为1,然后取其第一个元素,这应该等同于您使用str.partition时的结果。示例-

import re
testString = 'Tre Bröders Väg 6 2tr'
sep = '[0-9]tr'
head = re.split(sep,testString,1)[0]

演示 -

>>> import re
>>> testString = 'Tre Bröders Väg 6 2tr'
>>> sep = '[0-9]tr'
>>> head = re.split(sep,testString,1)[0]
>>> head
'Tre Bröders Väg 6 '

1

对于那些仍在寻找如何进行正则表达式分区的答案的人,请尝试以下函数:

import regex # re also works

def regex_partition(content, separator):
    separator_match = regex.search(separator, content)
    if not separator_match:
        return content, '', ''

    matched_separator = separator_match.group(0)
    parts = regex.split(matched_separator, content, 1)

    return parts[0], matched_separator, parts[1]

0

我来到这里是为了寻找一种使用基于正则表达式的partition()的方法。

正如yelichi answer中所提到的,如果分隔符包含一个捕获组,re.split()可以返回该分隔符,因此基于正则表达式创建分区函数的最基本方法如下:

re.split( "(%s)" % sep, testString, 1)

然而,这仅适用于简单的正则表达式。如果您正在使用分组的正则表达式进行拆分(即使是非捕获性的),它也不会提供预期的结果。

我最初看了skia.heliou answer提供的函数,但它需要无谓地再次运行正则表达式,并且更重要的是,如果模式本身不匹配(应该在匹配的分隔符上进行string.split,而不是re.split),则会失败。

因此,我实现了自己版本的支持正则表达式的partition():

def re_partition(pattern, string, return_match=False):
    '''Function akin to partition() but supporting a regex
    :param pattern: regex used to partition the content
    :param content: string being partitioned
    '''

    match = re.search(pattern, string)

    if not match:
        return string, '', ''

    return string[:match.start()], match if return_match else match.group(0), string[match.end():]


作为额外的功能,这可以返回匹配对象本身而不仅仅是匹配的字符串。这允许您直接与分隔符的组交互。
并且以迭代器形式:
def re_partition_iter(pattern, string, return_match=False):
    '''Returns an iterator of re_partition() output'''

    pos = 0
    pattern = re.compile(pattern)
    while True:
        match = pattern.search(string, pos)
        if not match:
            if pos < len(string):  # remove this line if you prefer to receive an empty string
                yield string[pos:]
            break

        yield string[pos:match.start()]
        yield match if return_match else match.group(0)
        pos = match.end()

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接