J'aimerais lire un fichier et mettre en majuscule les premières lettres d'une chaîne à l'aide de Python, mais certaines chaînes peuvent contenir des chiffres en premier. Le fichier pourrait ressembler à ceci:
"hello world"
"11hello world"
"66645world hello"
J'aimerais que ce soit:
"Hello world"
"11Hello world"
"66645World hello"
J'ai essayé ce qui suit, mais cela ne capitalise que si la lettre est en première position.
with open('input.txt') as input, open("output.txt", "a") as output:
for line in input:
output.write(line[0:1].upper()+line[1:-1].lower()+"\n")
Aucune suggestion? :-)
En utilisant des expressions régulières:
for line in output:
m = re.search('[a-zA-Z]', line);
if m is not None:
index = m.start()
output.write(line[0:index] + line[index].upper() + line[index + 1:])
Vous pouvez écrire une fonction avec une boucle for
:
x = "hello world"
y = "11hello world"
z = "66645world hello"
def capper(mystr):
for idx, i in enumerate(mystr):
if not i.isdigit(): # or if i.isalpha()
return ''.join(mystr[:idx] + mystr[idx:].capitalize())
return mystr
print(list(map(capper, (x, y, z))))
['Hello world', '11Hello world', '66645World hello']
Vous pouvez utiliser une expression régulière pour trouver la position du premier alphabet, puis utiliser upper()
sur cet index pour mettre ce caractère en majuscule. Quelque chose comme ça devrait marcher:
import re
s = "66645hello world"
m = re.search(r'[a-zA-Z]', s)
index = m.start()
Peut être utile d'essayer ...
>>> s = '11hello World'
>>> for i, c in enumerate(s):
... if not c.isdigit():
... break
...
>>> s[:i] + s[i:].capitalize()
'11Hello world'
Vous pouvez trouver le premier caractère alpha et le mettre en majuscule comme ceci:
with open("input.txt") as in_file, open("output.txt", "w") as out_file:
for line in in_file:
pos = next((i for i, e in enumerate(line) if e.isalpha()), 0)
line = line[:pos] + line[pos].upper() + line[pos + 1:]
out_file.write(line)
Quelles sorties:
Hello world
11Hello world
66645World hello
Que dis-tu de ça?
import re
text = "1234hello"
index = re.search("[a-zA-Z]", text).start()
text_list = list(text)
text_list[index] = text_list[index].upper()
''.join(text_list)
Le résultat est: 1234Hello
essaye ça:
with open('input.txt') as input, open("output.txt", "a") as output:
for line in input:
t_line = ""
for c in line:
if c.isalpha():
t_line += c.capitalize()
t_line += line[line.index(c)+1:]
break
else:
t_line += c
output.write(t_line)
Résultat d'exécution:
Hello world
11Hello world
66645World hello
Il existe probablement une approche REGEX sur une ligne, mais l’utilisation de title()
devrait également fonctionner:
def capitalise_first_letter(s):
spl = s.split()
return spl[0].title() + ' ' + ' '.join(spl[1:])
s = ['123hello world',
"hello world",
"11hello world",
"66645world hello"]
for i in s:
print(capitalise_first_letter(i))
Produire:
Hello world
11Hello world
66645World hello
Vous pouvez utiliser expression régulière pour cela:
import re
line = "66645world hello"
regex = re.compile(r'\D')
tofind = regex.search(line)
pos = line.find(tofind.group(0))+1
line = line[0:pos].upper()+line[pos:-pos].lower()+"\n"
print(line)
sortie: 66645World
Utilisation de isdigit () et title () pour les chaînes:
s = ['123hello world', "hello world", "11hello world", "66645world hello"]
print [each if each[0].isdigit() else each.title() for each in s ]
# ['123hello world', 'Hello World', '11hello world', '66645world hello']
La méthode title()
met en majuscule le premier caractère alpha de la chaîne et ignore les chiffres qui la précèdent. Cela fonctionne également bien pour les caractères non-ASCII, contrairement aux méthodes regex utilisant [a-zA-Z]
.
De la doc:
str.title ()
Renvoie une version titrée de la chaîne où les mots Commencent par un caractère majuscule et les caractères restants sont Minuscules. [...] L'algorithme utilise une simple définition Indépendante du langage d'un mot en tant que groupes de lettres consécutives. La définition Fonctionne dans de nombreux contextes, mais cela signifie que les apostrophes dans les contractions Et les possessifs forment des frontières de Word, qui peuvent ne pas être le résultat souhaité :
Nous pouvons en profiter de cette façon:
def my_capitalize(s):
first, rest = s.split(maxsplit=1)
split_on_quote = first.split("'", maxsplit=1)
split_on_quote[0] = split_on_quote[0].title()
first = "'".join(split_on_quote)
return first + ' ' + rest
Quelques tests:
tests = ["hello world", "11hello world", "66645world hello", "123ça marche!", "234i'm good"]
for s in tests:
print(my_capitalize(s))
# Hello world
# 11Hello world
# 66645World hello
# 123Ça marche! # The non-ASCII ç was turned to uppercase
# 234I'm good # Words containing a quote are treated properly
Avec re.sub
et repl en tant que fonction:
Si repl est une fonction, elle est appelée pour chaque occurrence de modèle Ne se chevauchant pas. La fonction prend un seul argument De correspondance et renvoie la chaîne de remplacement.
def capitalize(m):
return m.group(1) + m.group(2).upper() + m.group(3)
lines = ["hello world", "11hello world", "66645world hello"]
for line in lines:
print re.sub(r'(\d*)(\D)(.*)', capitalize, line)
Sortie:
Bonjour tout le monde 11Bonne monde 66645World Bonjour
Comme ceci, par exemple:
import re
re_numstart = re.compile(r'^([0-9]*)(.*)')
def capfirst(s):
ma = re_numstart.match(s)
return ma.group(1) + ma.group(2).capitalize()
Bon, il y a déjà beaucoup de réponses, ça devrait marcher.
Je les trouve trop compliqués ou complexes, mais ...
Voici une solution plus simple:
for s in ("hello world", "11hello world", "66645world hello"):
first_letter = next(c for c in s if not c.isdigit())
print(s.replace(first_letter, first_letter.upper(), 1))