如何分割字符串并在其中保留分隔符

时间:2019-04-26 23:35:02

标签: python regex

@edzech询问如何分割字符串并将分隔符保留在其中。他的问题是marked as duplicate,而此处的方法不同于“重复”方法。

我们想分割一个字符串,但是通过保留定界符,我们不希望它们被分开。 简而言之,对于<abc>d<e><f>ghi<j>,我们想要:

['<abc>', 'd', '<e>', '<f>', 'ghi', '<j>']

代替:

['<', 'abc', '>' 'd', '<', 'e', '>', '<', 'f', '>', 'ghi', '<', 'j', '>']

使用split无济于事,因为它会根据分隔符 split 。我们希望将其附加到其内容上。

3 个答案:

答案 0 :(得分:1)

这是解决方案。

import re

content = "<abc>d<e><f>ghi<j>"
result = re.findall(r"<.*?>|[^<>]+", content)

print(result)

输出:

['<abc>', 'd', '<e>', '<f>', 'ghi', '<j>']

说明:

  • regex <.*?>表示与<content>匹配的所有内容
  • regex [^<>]+表示其他所有内容

简而言之,findall将找到与<content>匹配的所有内容,否则,将找到其他所有内容。这样,内容将被分割而不会丢失分隔符。

答案 1 :(得分:1)

我相信您可以在此正则表达式中使用split

(?<=>)(?=[a-z<])|(?<=[a-z>])(?=<)

https://regex101.com/r/WNy5n9/1

只有两个选项具有成对的lookbehind / ahead断言。

扩展

   (?<= > )                      # Behind a  >
   (?= [a-z<] )                  # Ahead either a-z or <
|                              # or,
   (?<= [a-z>] )                 # Behind either a-z or >
   (?= < )                       # Ahead a  <

更新
请注意,在3.7版之前的Python版本中,拆分
空匹配中的内容未正确处理。
大概他们无法分辨出空白与空白之间的区别
字符串和/或如何进行零宽度匹配时的碰撞

好像他们在3.7版中将脑袋从a **中拔了出来,
所以你去..

演示

版本3.7.3

>>> import sys
>>> print( sys.version )
3.7.3 (v3.7.3:ef4ec6ed12, Mar 25 2019, 21:26:53) [MSC v.1916 32 bit (Intel)]

代码

>>> import re
>>> rx = re.compile( r"(?<=>)(?=[a-z<])|(?<=[a-z>])(?=<)" )
>>> s = "<abc>d<e><f>ghi<j>test><g>"
>>> x =  re.split( rx, s )
>>> print ( x )
['<abc>', 'd', '<e>', '<f>', 'ghi', '<j>', 'test>', '<g>']

答案 2 :(得分:1)

在提议的解决方案中,不属于对<>的单个开头<或结尾>排除在结果之外。

如果您还想保留<>,则可以使用:

<[^<>]*>|(?:(?!<[^<>]*>).)+

说明

  • <[^<>]*>匹配开局<,然后匹配0次以上而不是>,然后结束>
  • |
  • (?:(?!<[^<>]*>).)+脾气暴躁的令牌,如果在右边的直接字符不是从头到尾的模式,则匹配任何字符

Regex demo | Python demo

例如:

import re
content = "<abc>d<e><f>ghi<j>test><g>"
result = re.findall(r"<[^<>]*>|(?:(?!<[^<>]*>).)+", content)
print(result)

结果

['<abc>', 'd', '<e>', '<f>', 'ghi', '<j>', 'test>', '<g>']