Objectif : Pour traiter une liste AppleScript de chaînes de caractères de manière à ce que chaque chaîne soit filtrée pour supprimer tout caractère non numérique suivi de tous les zéros de tête. Les chaînes vides résultantes sont éliminées.
property digits : "0123456789"
property text item delimiters : {}
set L to {"abc", "qwerty.24", "01 abc23xyz", "123abc456", "2.1abc", "20"}
repeat with textItem in L
set stringOfDigits to filterCharacters from textItem thru digits
set numericalString to the processedNumericalString(stringOfDigits)
set the contents of the textItem to the numericalString
end repeat
return the strings in L --> {"24", "123", "123456", "21", "20"}
------------------------------------------------------------------------------------------
# HANDLERS:
to filterCharacters from someText as text thru allowedCharacters as text
local someText, allowedCharacters
set tid to my text item delimiters -- to reset them after
set my text item delimiters to {missing value} & characters in the allowedCharacters
set illegalCharacters to characters of (text items of someText as text)
set my text item delimiters to {missing value} & the illegalCharacters
set filteredText to the text items of someText as text
set my text item delimiters to tid
return the filteredText
end filterCharacters
on processedNumericalString(numericalString as text)
local numericalString
if the numericalString = "" then return missing value
try
the numericalString as number
on error
the numericalString
end try
return the result as text
end processedNumericalString
Ventilation
property
déclarations
A property
est similaire à une variable, à deux différences près : les propriétés sont persistant et ont portée mondiale ; les variables sont éliminées à la fin d'un script, et ont une portée locale par défaut. Je vous laisse rechercher ces termes si vous en avez besoin, car cela dépasse le cadre de cette réponse. Je n'utilise presque jamais un property
pour l'une ou l'autre des caractéristiques que je viens de mentionner. Plutôt, je les utilise le plus souvent pour séparer le stockage des valeurs que j'ai généralement l'intention de rester constant tout au long du script (par opposition aux variables dont on peut s'attendre à ce qu'elles changent à tout moment). AppleScript ne dispose pas d'un moyen de déclarer des constantes comme d'autres langages, donc c'est juste une bâtardisation d'une autre construction.
Manipulateurs
Les gestionnaires dans AppleScript peuvent être considérés comme ce que d'autres langages appellent une fonction, et les différences réelles sont nuancées et surtout académiques, avec une implication pratique étant que les gestionnaires ne sont pas conscients d'eux-mêmes et ne peuvent donc pas vous rapporter d'informations les concernant. Mais, comme les fonctions, ils reçoivent des arguments (ou des paramètres), font quelque chose avec eux et renvoient un résultat à la fin dans la plupart des cas.
-
filterCharacters
: C'est le cœur du script, là où le gros du travail est fait. Il reçoit un seul morceau de texte que vous souhaitez filtrer, et une liste de caractères autorisés, et supprime tout le reste, c'est-à-dire qu'il extrait les occurrences des caractères autorisés dans l'ordre où ils apparaissent. Pour ce faire, il utilise l'outil AppleScript text item delimiters
Il supprime essentiellement toutes les instances de délimiteurs dans la liste que vous lui fournissez, en divisant la chaîne en fragments aux points de suppression. Ainsi, il réalise presque la fonction opposée que nous voulons, et peut être considéré comme un filtre de texte auquel vous fournissez une liste de clandestins plutôt qu'une liste de admissible . C'est pourquoi je les utilise deux fois : d'abord pour éliminer les personnes autorisées, ne laissant que les illégaux ; ensuite, je redonne cette liste d'illégaux à la Commission européenne. text item delimiters
qui sont ensuite supprimés du texte original, ce qui nous laisse uniquement des éléments autorisés. Très efficace ; évite d'itérer à travers les caractères du morceau de texte.
-
processedNumericalString():
Ce gestionnaire est juste un moyen bon marché et paresseux de supprimer les zéros de tête une fois que le premier gestionnaire nous a donné une chaîne ne contenant que des chiffres. Il serait sans doute plus correct d'itérer à travers chaque caractère numérique jusqu'à atteindre le premier caractère non-zéro, en supprimant ceux qui le sont, avec un cas spécial pour éviter que "0"
en cours d'oblitération. Mais, à la place, j'ai juste décidé de contraindre le string
à un number
puis retour à un string
. Un hack qui fonctionne efficacement et que l'on suppose plus rapide aussi (bien que ce ne soit pas définitif).
Le corps principal du script.
Avec les deux gestionnaires définis au bas du script, il ne reste plus qu'à itérer dans la liste des chaînes de caractères, en envoyant chaque chaîne tour à tour à chaque gestionnaire. Ce qui revient est le morceau de texte que vous désirez, à savoir set the contents of...
est ce qui me permet de remplacer l'élément original de la liste par la nouvelle version. J'ai veillé à ne pas conserver les chaînes vides ( ""
), et le processedNumericalString()
remplace ces objets par un objet AppleScript appelé missing value
qui représente exactement ce qu'il dit (il s'agit de l'objet AppleScript prédéfini le plus proche de ce que les autres langages nomment souvent null
o nil
). Quoi qu'il en soit, l'important c'est que n'est pas a string
car la dernière ligne de l'exécution du script est :
return the strings in L
et c'est exactement ce que cela fait : tout élément de la liste qui n'est pas un string
(ou text
) de la classe d'objet est rejetée. Vous pouvez, bien sûr, remplacer cette ligne par :
set myVar to the strings in L
si vous avez besoin qu'il soit assigné à une variable afin de continuer à l'utiliser.
ADDENDUM
Le PO a ajouté :
La liste que j'ai décrite comme myVar
dans le poste original est toujours en train de changer au fil du temps, je veux que le processus de prise des éléments dans myVar
et isoler tous les chiffres pour les répéter indéfiniment.
OK. Mettons la partie principale du script dans un autre gestionnaire :
to formNumericalStringsWithItems from L as list
local L
repeat with textItem in L
set stringOfDigits to filterCharacters from textItem thru digits
set numericalString to the processedNumericalString(stringOfDigits)
set the contents of the textItem to the numericalString
end repeat
return the strings in L
end formNumericalStringsWithItems
Placez ceci avec les autres handlers pour le garder séparé et hors du chemin maintenant. Le corps principal du script est réduit à ces deux lignes, où j'ai utilisé l'identifiant myVar
au lieu de L
juste pour la clarté :
set myVar to {"abc", "qwerty.24", "01 abc23xyz", "123abc456", "2.1abc", "20"}
set myNewAndImprovedVar to formNumericalStringsWithItems from myVar
Maintenant, partout où myVar
dans votre script est mis à jour/changé, vous le suivez avec un appel à ce nouveau gestionnaire, comme je l'ai illustré ici.
Soyez clair sur la façon dont j'ai délimité les différentes "parties" du script : garder le property
déclarations au sommet- Ne le fais pas. mettez-les à l'intérieur de votre boucle de répétition ; ne mettez pas non plus les déclarations de handlers à l'intérieur de la boucle de répétition - je mets toutes les miennes au bas du script, où j'ai marqué une ligne et dirigé une section uniquement pour les handlers. Le "corps principal" du script (bien qu'il n'y ait plus que deux lignes ici) est ce que votre code occupera, donc gardez les choses bien rangées et groupées (c'est pourquoi je sépare les sections property
les déclarations du corps principal par deux sauts de paragraphe au lieu d'un seul).
1 votes
Pourriez-vous donner une liste plus variée d'exemples d'articles et, surtout, indiquer quel serait le résultat souhaité ? Par exemple, est-ce que
"123abc456"
carte vers{"123", "456"}
ou simplement"123"
ou simplement"456"
ou"123456"
ou"123 456"
? Une question apparemment simple donne lieu à de multiples solutions possibles, et il n'y a aucun moyen de savoir laquelle vous considérez comme "la bonne". Vous devez être précis et essayer de couvrir tous vos scénarios, sinon vous n'obtiendrez pas de solutions optimales. Vous pouvez modifier la question pour changer/ajouter des informations si nécessaire.0 votes
Ok, j'ai ajouté quelques informations supplémentaires sur ce que je veux que le résultat soit. La solution que je veux obtenir est assez large, donc peu importe à quoi elle correspond, du moment que tout le texte est supprimé de chaque élément.
1 votes
C'est un peu plus clair. Autre chose : vous avez été imprécis dans votre définition de ce que signifie "texte" est et ce qu'est un "nombre" est. Je pense savoir ce que vous voulez, mais pour plus de clarté : voulez-vous dire que vous voulez seulement chiffre caractères conservés dans le texte, mais les éléments finaux doivent rester sous forme de texte, par ex.
"23"
(c'est pas un nombre ; c'est un texte qui contient des caractères numériques et qui constitue la représentation textuelle d'un nombre) ; et que vous faites pas vous voulez que les éléments finaux soient retournés sous forme de nombres, par ex.23
. Résumé : OUI :{"24", "23", "22", "21", "20"}
; NON :{24, 23, 22, 21, 20}
. Correct ?0 votes
Et... Qu'en est-il des représentations non entières et des zéros de tête ou de queue ? Est-ce que
"0abc.12300"
revenir en tant que"0.12300"
o".12300"
o".123"
o"012300"
o"12300"
?0 votes
Il ne devrait pas y avoir de chiffres qui ne soient pas des nombres entiers, mais si un point apparaît avant, après ou entre un chiffre, il devrait également être supprimé. S'il y a un 0 en tête, il faut descendre jusqu'au nombre sans le 0. Ainsi, "0abc.12300" doit être "12300".
0 votes
Peu importe qu'il s'agisse de représentations textuelles du nombre ou du nombre lui-même. Mais oui, il est préférable que ce soit des représentations textuelles.