J'ai une liste de codes de produits dans un fichier texte, sur chaque comme est le code de produit qui ressemble à:
abcd2343 abw34324 abc3243-23A
Il s'agit donc de lettres suivis de chiffres et autres caractères.
Je veux split sur le première occurrence d'un nombre.
In [32]: import re
In [33]: s='abcd2343 abw34324 abc3243-23A'
In [34]: re.split('(\d+)',s)
Out[34]: ['abcd', '2343', ' abw', '34324', ' abc', '3243', '-', '23', 'A']
Ou, si vous souhaitez diviser la première occurrence d'un chiffre:
In [43]: re.findall('\d*\D+',s)
Out[43]: ['abcd', '2343 abw', '34324 abc', '3243-', '23A']
\d+
Correspond à 1 ou plusieurs chiffres.\d*\D+
Correspond à 0 ou plusieurs chiffres suivis de 1 ou plusieurs non-chiffres.\d+|\D+
Correspond à 1 ou plusieurs chiffres ou 1 ou plusieurs non-chiffres.Consultez la documentation pour en savoir plus sur la syntaxe des expressions rationnelles de Python.
re.split(pat, s)
divisera la chaîne s
en utilisant pat
comme délimiteur. Si pat
commence et se termine par des parenthèses (afin d'être un "groupe de capture"), alors re.split
Renverra également les sous-chaînes correspondant à pat
. Par exemple, comparez:
In [113]: re.split('\d+', s)
Out[113]: ['abcd', ' abw', ' abc', '-', 'A'] # <-- just the non-matching parts
In [114]: re.split('(\d+)', s)
Out[114]: ['abcd', '2343', ' abw', '34324', ' abc', '3243', '-', '23', 'A'] # <-- both the non-matching parts and the captured groups
En revanche, re.findall(pat, s)
renvoie uniquement les parties de s
qui correspondent à pat
:
In [115]: re.findall('\d+', s)
Out[115]: ['2343', '34324', '3243', '23']
Ainsi, si s
se termine par un chiffre, vous pouvez éviter de terminer par une chaîne vide en utilisant re.findall('\d+|\D+', s)
au lieu de re.split('(\d+)', s)
:
In [118]: s='abcd2343 abw34324 abc3243-23A 123'
In [119]: re.split('(\d+)', s)
Out[119]: ['abcd', '2343', ' abw', '34324', ' abc', '3243', '-', '23', 'A ', '123', '']
In [120]: re.findall('\d+|\D+', s)
Out[120]: ['abcd', '2343', ' abw', '34324', ' abc', '3243', '-', '23', 'A ', '123']
import re
m = re.match(r"(?P<letters>[a-zA-Z]+)(?P<the_rest>.+)$",input)
m.group('letters')
m.group('the_rest')
Cela couvre votre cas d'angle abc3243-23A et produira abc
pour le groupe de lettres et 3243-23A pour the_rest
Puisque vous avez dit qu'ils sont tous sur des lignes individuelles, vous devrez évidemment mettre une ligne à la fois dans input
Pour partitionner sur le premier chiffre
parts = re.split('(\d.*)','abcd2343') # => ['abcd', '2343', '']
parts = re.split('(\d.*)','abc3243-23A') # => ['abc', '3243-23A', '']
Ainsi, les deux parties sont toujours des parties [0] et des parties [1].
Bien sûr, vous pouvez l'appliquer à plusieurs codes:
>>> s = "abcd2343 abw34324 abc3243-23A"
>>> results = [re.split('(\d.*)', pcode) for pcode in s.split(' ')]
>>> results
[['abcd', '2343', ''], ['abw', '34324', ''], ['abc', '3243-23A', '']]
Si chaque code est sur une ligne individuelle, au lieu de s.split( )
utilisez s.splitlines()
.
Essayez ce code, cela fonctionnera bien
import re
text = "MARIA APARECIDA 99223-2000 / 98450-8026"
parts = re.split(r' (?=\d)',text, 1)
print(parts)
Production:
["MARIA APARECIDA", "99223-2000/98450-8026"]
def firstIntIndex(string):
result = -1
for k in range(0, len(string)):
if (bool(re.match('\d', string[k]))):
result = k
break
return result