Python正则表达式拆分保持拆分模式字符

时间:2012-03-16 19:08:13

标签: python regex

最简单的解释方法就是一个例子: 我有这个字符串:'Docs / src / Scripts / temp' 我知道如何分割两种不同的方式:

re.split('/', 'Docs/src/Scripts/temp') -> ['Docs', 'src', 'Scripts', 'temp']

re.split('(/)', 'Docs/src/Scripts/temp') -> ['Docs', '/', 'src', '/', 'Scripts', '/', 'temp']

是否有一种方法可以通过正斜杠进行分割,但保留斜杠的一部分? 例如,我希望上面的字符串看起来像这样:

['Docs/', '/src/', '/Scripts/', '/temp']

任何帮助将不胜感激!

6 个答案:

答案 0 :(得分:8)

有趣的问题,我建议做这样的事情:

>>> 'Docs/src/Scripts/temp'.replace('/', '/\x00/').split('\x00')
['Docs/', '/src/', '/Scripts/', '/temp']

这里的想法是首先将所有/个字符替换为两个/字符,这两个字符由一个特殊字符分隔,该特殊字符不是原始字符串的一部分。我使用了一个空字节('\x00'),但您可以将其更改为其他内容,然后最终拆分为该特殊字符。

正则表达式在这里实际上并不是很好,因为你无法拆分零长度匹配,re.findall()找不到重叠匹配,所以你可能需要对字符串进行多次传递。

此外,re.split('/', s)将执行与s.split('/')相同的操作,但第二种更有效。

答案 1 :(得分:5)

没有split()但具有前瞻性的解决方案:

>>> s = 'Docs/src/Scripts/temp'
>>> r = re.compile(r"(?=((?:^|/)[^/]*/?))")
>>> r.findall(s)
['Docs/', '/src/', '/Scripts/', '/temp']

<强>解释

(?=        # Assert that it's possible to match...
 (         # and capture...
  (?:^|/)  #  the start of the string or a slash
  [^/]*    #  any number of non-slash characters
  /?       #  and (optionally) an ending slash.
 )         # End of capturing group
)          # End of lookahead

由于在字符串中的每个位置都尝试了先行断言,并且不使用任何字符,因此重叠匹配没有问题。

答案 2 :(得分:3)

1)您不需要将正则表达式拆分为单个固定字符:

>>> 'Docs/src/Scripts/temp'.split('/')

['Docs','src','Scripts','temp']

2)考虑使用这种方法:

import os.path

def components(path):
    start = 0
    for end, c in enumerate(path):
        if c == os.path.sep:
            yield path[start:end+1]
            start = end
    yield path[start:]

在我看来,它不依赖于分裂连接分裂等聪明的技巧,这使得它更具可读性。

答案 3 :(得分:2)

如果你不坚持在两边都有斜线,那实际上很简单:

>>> re.findall(r"([^/]*/)", 'Docs/src/Scripts/temp')
['Docs/', 'src/', 'Scripts/']

对于重叠的字符串,re和split都没有被删除,所以如果这是你真正想要的,我只是在每个结果的开头添加一个斜杠,除了第一个。

答案 4 :(得分:2)

试试这个:

re.split(r'(/)', 'Docs/src/Scripts/temp')

来自python的文档

  

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

     

按字符串拆分字符串   模式的出现。 如果在模式中使用捕获括号,   那么模式中所有组的文本也作为一部分返回   结果列表。 如果maxsplit非零,则最多maxsplit拆分   发生,并将字符串的其余部分作为最终字符串返回   列表的元素。 (不兼容性说明:在原始的Python 1.5中   发布时,maxsplit被忽略了。这已在以后的版本中修复。)

答案 5 :(得分:1)

我不确定有一种简单的方法可以做到这一点。这是我能想到的最好的......

import re

lSplit = re.split('/', 'Docs/src/Scripts/temp')
print [lSplit[0]+'/'] + ['/'+x+'/' for x in lSplit][1:-1] + ['/'+lSplit[len(lSplit)-1]]

有点乱,但确实做了你想做的事。