python re.split():如何保存一些分隔符(而不是使用括号保存所有分隔符)
以下句子:python re.split():如何保存一些分隔符(而不是使用括号保存所有分隔符),python,split,Python,Split,以下句子: "I am very hungry, so mum brings me a cake! 我希望它被分隔符分割,我希望除了空间之外的所有分隔符也被保存。因此,预期产出为: "I" "am" "very" "hungry" "," "so", "mum" "brings" "me" "a" "cake" "!" "\n" 我目前正在做的是re.split(r'([!:'',(\s+)\n]),text),它可以拆分整个句子,但也节省了很多我
"I am very hungry, so mum brings me a cake!
我希望它被分隔符分割,我希望除了空间之外的所有分隔符也被保存。因此,预期产出为:
"I" "am" "very" "hungry" "," "so", "mum" "brings" "me" "a" "cake" "!" "\n"
我目前正在做的是
re.split(r'([!:'',(\s+)\n]),text)
,它可以拆分整个句子,但也节省了很多我不想要的空格字符。我还尝试了正则表达式\s |([!:'',(\s+)\n])
,不知何故,这给了我很多空白。这是因为正则表达式包含一个捕获组。由于该捕获组,它还将在结果中包含匹配项。但这可能是你想要的
唯一的挑战是过滤出None
s(以及其他真实值False
)如果不匹配,我们可以使用以下方法:
def tokenize(text):
return filter(None, re.split(r'[ ]+|([!:''".,\s\n])', text))
一种方法是用空格包围特殊字符(,!。\n)
,然后按空格分割:
import re
def tokenize(t, pattern="([,!.\n])"):
return [e for e in re.sub(pattern, r" \1 ", t).split(' ') if e]
s = "I am very hungry, so mum brings me a cake!\n"
print(tokenize(s))
输出
['I', 'am', 'very', 'hungry', ',', 'so', 'mum', 'brings', 'me', 'a', 'cake', '!', '\n']
search
或findall
在这里可能比split
更合适:
import re
s = "I am very hungry, so mum brings me a !#$#@ cake!"
print(re.findall(r'[^\w\s]+|\w+', s))
# ['I', 'am', 'very', 'hungry', ',', 'so', 'mum', 'brings', 'me', 'a', '!#$#@', 'cake', '!']
模式[^\w\s]+|\w+
的意思是:既不是字母数字也不是空格的符号序列,或者是字母数字序列(即一个单词)几乎是的副本。为什么将[]+\124;添加到reg表达式中会导致生成大量的非?I@SoManyProblems:因为如果捕获组(括号中的部分)不匹配任何内容,它仍然会为“空”捕获组引入一个None
。如果您生成多个括号,这甚至会导致大量额外的元素。非常感谢您的回复。为了确认我对您的理解是正确的,您的意思是[]+匹配空格,所以它进行了拆分工作,并且因为它没有(),所以它不会返回任何内容?@SoManyProblems:regex本身有一个(…)
,一个捕获组。但由于该捕获组未“激活”(它不匹配任何内容),因此它捕获None
。您能否解释一下该模式是如何以这种方式构建的?为什么[^\w\s]+给出了所有单词,但没有给出带空格字符的单词(如建议的那样)?还有,你为什么在那里放置| w+模式?@SoManyProblems:添加了一个解释
import re
s = "I am very hungry, so mum brings me a !#$#@ cake!"
print(re.findall(r'[^\w\s]+|\w+', s))
# ['I', 'am', 'very', 'hungry', ',', 'so', 'mum', 'brings', 'me', 'a', '!#$#@', 'cake', '!']