Je veux savoir quels mots peuvent être formés en utilisant les noms de notes de musique.
cette question est très similaire: Python qui trouvera des mots faits de lettres spécifiques. N'importe quel sous-ensemble de lettres peut être utilisé Mais mon alphabet contient aussi «fis», «cis» et ainsi de suite.
import re
from tkinter import filedialog as fd
m = re.compile('^(fis|ges|gis|as|ais|cis|des|es|dis|[abcfhg])+$')
matches = list()
filename = fd.askopenfilename()
with open(filename) as f:
for line in f:
if m.match(str(line).lower()) is not None:
matches.append(line[:-1])
print(matches)
J'ai une très longue liste de mots avec un mot par liste et je veux utiliser p >
>>> import re
>>> m = re.compile('^[abilrstu]+$')
>>> m.match('australia') is not None
True
>>> m.match('dummy') is not None
False
>>> m.match('australian') is not None
False
pour vérifier si chaque mot fait partie de cette "langue", puis l'enregistrer dans un autre fichier.
mon problème est de savoir comment modifier
with open(...) as f:
for line in f:
if
donc il correspond également avec "fis", "cis" et ainsi de suite.
par exemple "fish" est une correspondance mais "ifsh" n'est pas une correspondance.
Modifier: solution avec tk inter fenêtre s'ouvrant pour choisir le fichier:
letters = ["c","d","e","f","g","a","h","c","fis","cis","dis"]
3 Réponses :
Cette fonction fonctionne, elle n'utilise aucune bibliothèque externe:
func("banana", {'na', 'chicken', 'b', 'ba'})
elle fonctionne car if s == "" , alors elle a été décomposée en vos lettres.
Il semble que mon explication ne soit pas claire. WORD.replace (LETTER, "") remplacera la note / LETTER dans WORD par rien, voici un exemple:
func("banana", {'na'})
il remplacera chaque 'na' dans "banane" par rien ( '' )
le résultat après ceci est "ba" , ce qui n'est pas une note
not "" signifie True et pas "ba" est faux, c'est du sucre syntaxique.
voici un autre exemple:
def func(word, letters):
for l in sorted(letters, key=lambda x: x.length, reverse=True):
word = word.replace(l, "")
return not s
il remplacera chaque 'poulet' dans "banane" par rien ( '' )
le résultat après ceci est "banana"
il remplacera chaque 'ba' dans "banana" par rien ( '' )
le résultat après ceci est "nana"
il remplacera chaque 'na' dans "nana" par rien ( '' )
le résultat après ceci est ""
il remplacera chaque 'b' dans "" par rien ( '' )
le résultat après ceci est ""
not "" est True ==> HURRAY IT IS A MELODY!
remarque: La raison du trié par longueur, car sinon, le deuxième exemple n'aurait pas fonctionné. Le résultat après la suppression de "b" serait "a", qui ne peut pas être décomposé en notes.
Je ne comprends pas tout à fait, pouvez-vous expliquer comment ce code fonctionne?
même si stackoverflow ne veut pas que j'utilise les commentaires pour cela: merci d'avoir pris le temps d'expliquer comment cela fonctionne et de fournir une solution non regex. J'ai accepté l'autre parce que j'ai demandé dans la question comment modifier l'expression régulière, donc votre réponse est strictement une réponse à ma question. toujours upvote car c'est une alternative intéressante.
Et je vous remercie d'avoir demandé quand vous n'avez pas compris, l'objectif de SO est de fournir des réponses et d'apprendre. Je suis heureux d'avoir atteint ces objectifs.
Je pense que ^ (fis | cis | dis | [abcfhg]) + $ fera l'affaire.
Une déconstruction de ce qui se passe ici:
| fonctionne comme OR conjonction [...] désigne "n'importe quel symbole de ce qui est entre crochets" ^ et $ représentent respectivement le début et la fin de la ligne + signifie "1 fois ou plus" (...) signifie regroupement, nécessaire pour appliquer les modificateurs + / * / {} . Sans regrouper ces modificateurs, s'applique à l'expression de gauche la plus proche Dans l'ensemble, cette chaîne "lit" comme "une chaîne entière est une ou plusieurs répétitions de fis / cis / dis ou de abcfhg"
Vous voulez probablement + plutôt que *
Eh bien, je pense que cette chaîne vide peut être considérée comme une ligne composée de n'importe quel caractère
travaillé pour moi avec un + à la fin. veuillez élaborer un peu le code comme l'a souligné @DebanjanB. vous êtes invités à utiliser mon code que j'ai mis dans la question
Vous pouvez calculer le nombre de lettres de toutes les unités (noms des notes de musique), qui sont dans le mot, et comparer ce nombre à la longueur du mot.
from collections import Counter
units = {"c","d","e","f","g","a","h", "fis","cis","dis"}
def func(word, units=units):
letters_count = Counter()
for unit in units:
num_of_units = word.count(unit)
letters_count[unit] += num_of_units * len(unit)
if len(unit) == 1:
continue
# if the unit consists of more than 1 letter (e.g. dis)
# check if these letters are in one letter units
# if yes, substruct the number of repeating letters
for letter in unit:
if letter in units:
letters_count[letter] -= num_of_units
return len(word) == sum(letters_count.values())
print(func('disc'))
print(func('disco'))
# True
# False
Vérifiez si vous voulez faire
(^ | \ b) ([cdefgahc] fis | cis | dis) + (\ b | $)regex101.com/r/RzYRIs/1je suppose que
"h"doit être un"b"@ParitoshSingh Pas nécessairement: le système allemand (qui est évidemment celui qui est utilisé ici), appelle H ce qui dans les pays anglophones s'appelle B, et utilise B pour ce que dans les pays anglophones s'appelle B-flat.
ooh, je ne savais pas ça, merci @BoarGules
@BoarGules est un système de notation allemand correct.