产品代码看起来像abcd2343,如何按字母和数字拆分?

60

我有一个文本文件里面记录了一些产品代码,每行一个,格式如下:

abcd2343 abw34324 abc3243-23A

所以它们由字母数字其他字符组成。

我想要在第一个数字出现的地方进行分割

6个回答

94
import re
s='abcd2343 abw34324 abc3243-23A'
re.split('(\d+)',s)

> ['abcd', '2343', ' abw', '34324', ' abc', '3243', '-', '23', 'A']

或者,如果您想在第一个数字出现时进行分割:

re.findall('\d*\D+',s)
> ['abcd', '2343 abw', '34324 abc', '3243-', '23A']

  • \d+ 匹配1个或多个数字。
  • \d*\D+ 匹配0个或多个数字后跟1个或多个非数字字符。
  • \d+|\D+ 匹配1个或多个数字 1个或多个非数字字符。

查看文档,了解有关Python正则表达式语法的更多信息。


re.split(pat, s)会使用pat作为分隔符拆分字符串s。如果pat以括号开头和结尾(从而成为“捕获组”),那么re.split还将返回与pat匹配的子字符串。例如比较:

re.split('\d+', s)
> ['abcd', ' abw', ' abc', '-', 'A']   # <-- just the non-matching parts

re.split('(\d+)', s)
> ['abcd', '2343', ' abw', '34324', ' abc', '3243', '-', '23', 'A']  # <-- both the non-matching parts and the captured groups

相比之下,re.findall(pat, s)仅返回与pat匹配的s部分:

re.findall('\d+', s)
> ['2343', '34324', '3243', '23']

因此,如果 s 以数字结尾,您可以使用 re.findall('\d+|\D+', s) 而不是使用 re.split('(\d+)', s) 来避免以空字符串结尾:

s='abcd2343 abw34324 abc3243-23A 123'

re.split('(\d+)', s)
> ['abcd', '2343', ' abw', '34324', ' abc', '3243', '-', '23', 'A ', '123', '']

re.findall('\d+|\D+', s)
> ['abcd', '2343', ' abw', '34324', ' abc', '3243', '-', '23', 'A ', '123']

4
如果在字符串结尾处使用“(\d+)”,则列表中的最后一个条目将是空字符串。如何避免这种情况? - user124384
3
据我所理解,您可以使用re.findall('(\d+|\D+)', 'abcd2343 abw34324 abc3243-23'),它将返回['abcd', '2343', ' abw', '34324', ' abc', '3243', '-', '23'] - unutbu
你好,我该如何将此应用到整个列?我的“产品”列的格式为“-8937ADF”,我想在同一个数据帧中创建包含“-8937”和“ADF”的两个列。 - Baobab

9
此函数处理浮点数和负数。
def separate_number_chars(s):
    res = re.split('([-+]?\d+\.\d+)|([-+]?\d+)', s.strip())
    res_f = [r.strip() for r in res if r is not None and r.strip() != '']
    return res_f

例如:
utils.separate_number_chars('-12.1grams')
> ['-12.1', 'grams']

2
import re

m = re.match(r"(?P<letters>[a-zA-Z]+)(?P<the_rest>.+)$",input)

m.group('letters')
m.group('the_rest')

这个涵盖了你的特殊情况 abc3243-23A,并会输出abc作为字母组,而将 3243-23A 输出为 the_rest

由于你说他们都在单独行上,因此显然需要将每一行放入 input


1
def firstIntIndex(string):
    result = -1
    for k in range(0, len(string)):
        if (bool(re.match('\d', string[k]))):
            result = k
            break
    return result

1

根据第一位数字进行分区

parts = re.split('(\d.*)','abcd2343')      # => ['abcd', '2343', '']
parts = re.split('(\d.*)','abc3243-23A')   # => ['abc', '3243-23A', '']

因此,这两个部分始终是parts [0]和parts [1]。

当然,您可以将此应用于多个代码:

>>> s = "abcd2343 abw34324 abc3243-23A"
>>> results = [re.split('(\d.*)', pcode) for pcode in s.split(' ')]
>>> results
[['abcd', '2343', ''], ['abw', '34324', ''], ['abc', '3243-23A', '']]

如果每个代码都在单独的一行中,那么请使用 s.splitlines() 替代 s.split( )

1
尝试一下这段代码,它会正常工作。
import re
text = "MARIA APARECIDA 99223-2000 / 98450-8026"
parts = re.split(r' (?=\d)',text, 1)
print(parts)

输出:

['MARIA APARECIDA','99223-2000 / 98450-8026']


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