Python:通过数字、字母和- _ 来分割字符串

4

假设我有一个像这样的字符串

string = 'rename_file_1122--23-_12'

有没有一种方法可以像这样拆分

parts = ['rename','_','file','_','1122','--','23','-_','12']

我尝试使用正则表达式,但它不起作用。

import re

name_parts = re.findall('\d+|\D+|\w+|\W+', string)

结果如下:

['rename_file_', '1122', '--', '23', '-_', '12']

########## 第二部分

如果我有一个像这样的字符串:

string2 = 'Hello_-Marco5__-'

我需要使用哪些条件才能获得:['Hello','_-','Marco','5','__-'] 。我的目标是将一个字符串分成字母、数字和'-_'的组。

谢谢您的答复。

3个回答

8

您可以使用

re.findall(r'[^\W_]+|[\W_]+', string)

查看正则表达式演示

正则表达式详情:

  • [^\W_]+ - 一个或多个字符,除了非单词和_字符(因此是一个或多个字母或数字)
  • | - 或者
  • [\W_]+ - 一个或多个非单词和/或_ 字符

查看Python演示

import re
string = 'rename_file_1122--23-_12'
name_parts = re.findall(r'[^\W_]+|[\W_]+', string)
print(name_parts)
# => ['rename', '_', 'file', '_', '1122', '--', '23', '-_', '12']

2
当我看到这个正则表达式时,我做了几次双重检查,因为我想:“啥?匹配非-“某物”或匹配“某物”?那不会匹配所有内容吗?”这正是它需要做的——查找“非某物”或“某物”,并保持匹配,直到找到相反的。不错! - Pranav Hosangadi
3
这是一种标记化技术,它使用两个相反的独立选择在一个模式中。 最终,它可以匹配所有文本,只是将其拆分为两种标记类型。 根据标记类型,可能还有更多的选择。 - Wiktor Stribiżew

4

或者您可以使用groupby来自itertools

from itertools import groupby

string = 'rename_file_1122--23-_12'

result = [''.join(value) for key, value in groupby(string, key=str.isalnum)]

print(result)

输出:

['rename', '_', 'file', '_', '1122', '--', '23', '-_', '12']

编辑:

我想到了一个可能更简单的解决方案,使用正则表达式:

string = 'rename_file_1122--23-_12'
result = re.split('([_-]*)', string)
print(result)

相同的输出。

re.split 将根据匹配正则表达式来拆分字符串。我使用的表达式包括一个分组模式,而split会将匹配结果包含在拆分后的结果中:

([_-]*)

表示匹配(并记住结果)一个或多个_- 的序列。 * 表示一个或多个,[] 表示方括号内的任何内容。

如果没有使用分组,仅使用 [_-]*,我们将得到以下结果,但不包括匹配项:

string = 'rename_file_1122--23-_12'
result = re.split('[_-]*', string)
print(result)

输出:

['rename', 'file', '1122', '23', '12']

-1

我已经找到了第二部分的解决方案,如下所示:

name_parts=re.findall(r'[^\d_]+|[^\D]+|[^\W_]+|[\W_]+', string)

在问题中添加第二部分并不好。这会让我们的答案看起来不完整或不够专业。 - Peter Wood

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