Regex pour correspondre à toutes les instances non pas à l'intérieur des guillemets
De cette q/a, j'en ai déduit que toutes les instances d'une regex pas à l'intérieur des guillemets, c'est impossible. Qui est, il peut ne pas correspondre échappé guillemets (ex: "this whole \"match\" should be taken"
). Si il y a un moyen de le faire que je ne connais pas, qui permettrait de résoudre mon problème.
Si pas, cependant, je voudrais savoir si il existe une alternative efficace qui pourrait être utilisé en JavaScript. J'ai réfléchi un peu, mais ne pouvez pas venir avec quelque des solutions élégantes qui serait à l'œuvre dans la plupart, si pas tous les cas.
Plus précisément, j'ai juste besoin de l'alternative de travailler avec .split() et .replace() les méthodes, mais si elle pouvait être plus généralisée, qui serait le meilleur.
Par Exemple:
Une entrée de chaîne de:
+bar+baz"not+or\"+or+\"this+"foo+bar+
remplacement de + avec #, pas à l'intérieur des guillemets, serait de retour:
#bar#baz"not+or\"+or+\"this+"foo#bar#
Vous devez vous connecter pour publier un commentaire.
En fait, vous pouvez faire correspondre toutes les instances d'une regex pas à l'intérieur des guillemets pour toute chaîne de caractères, où chaque guillemet ouvrant est fermé à nouveau. Dire, comme vous l'exemple ci-dessus, vous voulez faire correspondre
\+
.L'observation clé ici est, qu'un mot est en dehors des guillemets s'il y a un même nombre de citations par la suite. Cela peut être modélisé comme un "look-ahead" affirmation:
Maintenant, vous voulez pas compter échappé citations. Cela devient un peu plus compliqué. Au lieu de
[^"]*
, qui a avancé à la prochaine citation, vous devez tenir compte de barres obliques inverses ainsi et l'utilisation[^"\\]*
. Après vous arrivez à une barre oblique inverse ou un devis, vous avez besoin d'ignorer le caractère suivant si vous rencontrez une barre oblique inverse, ou bien passer à la suivante sans échappement devis. Qui ressemble à(\\.|"([^"\\]*\\.)*[^"\\]*")
. Combiné, vous arrivez àJ'avoue c'est un peu cryptique. =)
?:
à l'intérieur de tous les parentheticals:\+(?=(?:[^"\\]*(?:\\.|"(?:[^"\\]*\\.)*[^"\\]*"))*[^"]*$)
'"'
...Ce serait provoquer le nombre de guillemets dans la chaîne àodd
Azmisov, ressusciter cette question parce que vous avez dit que vous cherchiez
any efficient alternative that could be used in JavaScript
etany elegant solutions that would work in most, if not all, cases
.Il arrive à être une simple solution générale qui n'était pas mentionné.
En comparaison avec les alternatives, la regex pour cette solution est d'une simplicité déconcertante:
L'idée est que nous avons du match, mais ignorer quoi que ce soit dans les citations à neutraliser que le contenu (sur le côté gauche de l'alternance). Sur le côté droit, nous saisissons toutes les
+
qui n'ont pas été neutralisé dans le Groupe 1, et la fonction remplacer examine Groupe 1. Ici est plein de code opérationnel:Démo en ligne
Vous pouvez utiliser le même principe pour le match ou split. Voir la question et l'article en référence, qui sera aussi le point de vous des exemples de code.
Espère que cela vous donne une idée différente de façon très générale pour ce faire. 🙂
Que sur les Cordes à Vide?
Ci-dessus est une réponse générale à la vitrine de la technique. Il peut être modifié en fonction de vos besoins précis. Si vous vous inquiétez que votre texte peut contenir des chaînes vides, il suffit de changer le quantificateur à l'intérieur de la chaîne de capture d'expression de
+
à*
:Voir démo.
Qu'en est Échappé d'un Devis?
Encore une fois, le ci-dessus est une réponse générale à la vitrine de la technique. Non seulement le "ignorer ce match" regex peut être raffiné à vos besoins, vous pouvez ajouter de multiples expressions de l'ignorer. Par exemple, si vous voulez vous assurer échappé citations sont correctement ignoré, vous pouvez commencer par l'ajout d'une alternance
\\"|
devant les deux autres dans le but de correspondre (ou ignorer) zigzaguant échappé guillemets.Ensuite, dans la section
"[^"]*"
qui capture le contenu de la double-cité des chaînes, vous pouvez ajouter une alternance afin d'assurer échappé guillemets sont appariés avant leur"
a une chance de se transformer en une clôture sentinelle, en le transformant en"(?:\\"|[^"])*"
L'expression qui en résulte comporte trois branches:
\\"
de match et ignorer"(?:\\"|[^"])*"
de match et ignorer(\+)
de match, capturer et de gérerNoter que dans d'autres regex saveurs, nous avons pu faire ce travail plus facilement avec lookbehind, mais JS ne le supporte pas.
La pleine regex devient:
Voir regex démo et le script complet.
Référence
if (group1 === undefined ) return m;
. Intéressant de noter que j'ai été à la recherche pour les places; pas de signes plus.""
et s'est échappé citations\"
. regex101.com/r/yR7xV5/1Vous pouvez le faire en trois étapes.
Code ci-dessous
Si vous exécutez après la mise
vous devriez obtenir
Il fonctionne, parce que après l'étape 1,
donc la seule des virgules dans myString sont des chaînes de caractères en dehors. L'étape 2, puis tourne les virgules dans les retours à la ligne:
Enfin nous remplacer les cordes qui ne contiennent que des nombres avec leur contenu original.
Bien que la réponse par zx81 semble être la plus performante et propre, il needes ces correctifs correctement rattraper les échappés citations:
et
Aussi le déjà mentionné "groupe1 === undefined" ou "!groupe1".
Surtout 2. semble important de prendre effectivement tout demandé dans la question d'origine en compte.
Il convient de mentionner que cette méthode est implicite dans la chaîne de ne pas avoir échappé à des citations à l'extérieur de devis sans échappement paires.