C'est l'une des choses les plus difficiles que j'ai jamais essayées. Au fil des ans, j'ai cherché mais je ne trouve tout simplement pas un moyen de faire cela - faire correspondre une chaîne non entourée d'un caractère donné, comme des citations ou une plus grande / moins que des symboles.
Une regex comme ceci pourrait correspondre aux URL Liens HTML, SQL Table.Columns Valeurs non dans les devis, et beaucoup d'autres choses. P>
\b(?:[^"'])([^"']+)(?:[^"'])\b
6 Réponses :
C'est un peu difficile. Il y a des moyens, tant que vous n'avez pas besoin de garder une trace de la nidification. Par exemple, évitons les choses citées: ou, expliquant: p> Maintenant, il y a d'autres façons de le faire, mais Peut-être, pas aussi flexible. Par exemple, si vous voulez le trouver, tant qu'il n'existait pas une séquence "//" ou "#" - en d'autres termes, une ceci en dehors d'un commentaire, vous pouvez le faire comme ceci: P > ici, comme pour tout des structures imbriquées arbitrairement em> nichées - n (? est un look négatif. Il ne correspond pas à ces personnages, mais il testera qu'ils n'apparaissent pas avant cela. P> ( code > fermé par N ) code>, par exemple - ils ne peuvent pas être représentés par des expressions régulières. Perl peut le faire, mais ce n'est pas une expression régulière. P> p>
Il est possible si n i> est fini (et pratique si n i> est petit), mais pas si la nidification peut être arbitrairement profonde.
C'est pédant, mais alors soyez-le. Fixé.
Eh bien, les expressions régulières ne sont que le mauvais outil pour cela, il est donc tout à fait naturel que c'est difficile. p>
Les choses "entourées" par d'autres choses ne sont pas des règles valides pour les grammaires ordinaires. La plupart (on pouvait peut-être dire que tous les langages sérieux) et les langages de programmation ne sont pas réguliers. Tant qu'il n'y a pas de nidification impliquée, vous pourrez peut-être simuler un analyseur avec une regex, mais assurez-vous de comprendre ce que vous faites. P>
pour HTML / XML, utilisez simplement un REEE HTML. Analyseur XML; ceux qui existent pour presque toutes les langues ou un cadre Web; Les utiliser généralement impliquent de quelques lignes de code. Pour les tables, vous pourrez peut-être utiliser un analyseur CSV ou, à une pincée, rouler votre propre analyseur qui extrait les pièces à l'intérieur / à l'extérieur. Après avoir extrait les pièces que vous êtes intéressé, vous pouvez utiliser une comparaison simple de chaîne ou des expressions régulières pour obtenir vos résultats. P>
+1 Juste ce que j'allais signaler. Fondamentalement, ce problème est difficile, tout comme la percer un trou avec un marteau est difficile.
"Entouré" est une règle valable pour les langues ordinaires. Nidification et inhorter, ce n'est pas le cas.
@Daniel: Règles valides dans les grammaires régulières (à droite) ne sont que des règles qui ont exactement une non-terminale du côté gauche et de la chaîne vide ou d'un terminal ou d'un terminal suivi d'un non mortal sur le côté droit. .
Q :: = "s; s :: = ae; s :: = <; s :: = ze; e :: = =" - Voilà, une lettre minuscule entourée de citations, dans un régulier grammaire. Y avait-il autre chose?
C'est ce que je voulais dire avec "simuler un analyseur".
La meilleure solution dépendra de ce que vous connaissez de l'entrée. Par exemple, si vous recherchez des choses qui ne sont pas enfermées dans des devis doubles, cela signifie-t-il que les doubles citations seront toujours correctement équilibrées? Peuvent-ils être échappés par des backslashes ou en les enfermant en guillemets célibataires?
En supposant que le cas le plus simple - pas de nidification, pas d'échappement - vous pouvez utiliser un lookahead comme ceci: P>
'Match THIS1 and "NOT THIS2" but THIS3 and "NOT "THIS4" or NOT THIS5" ' + 'but \"THIS6\" is good and \\\\"NOT THIS7\\\\".'
C'était un bon départ sur le sujet, mais je crains que cela ne cherche que "ceci" quand il s'agit de trois citations (") à l'écart de la fin de la chaîne.
Oups! J'ai laissé un ensemble de parenthèses. Essayez-le maintenant.
Très impressionnant. Avec un soutien pour une évasion, cela pourrait suffire! Preg_Match_All ('/ [^ "] + (? = (?: (?: (?: (?: [^"] * + ") {2}) * + [^"] * + \ z) /', $ String, $ matchs) ;
Bravo. Vous avez construit une regex qui peut faire manipuler des caractères échappés. Je dois admettre qu'en raison de ce que j'ose dire que vous êtes le meilleur gars de regex que j'ai jamais rencontré. Au fil des ans, d'autres viennent de rire et de briser leur tête face à ce problème.
Après avoir pensé à des éléments de nidification ("a" ceci et "this" "" ") et des articles revers" \ "\" this \ "" Il semble qu'il est vrai que ce n'est pas un travail de regex. Cependant, le seul chose que je puisse penser à résoudre ce problème serait une regex comme un analyseur Char-By-Char qui marquerait $ quote_level = ###; lors de la recherche et de la saisie d'une citation ou d'une sous-citation valide. De cette façon dans cette partie de la chaîne que vous sauriez si vous étiez à l'intérieur d'un personnage donné, même s'il est échappé par une barre oblique ou autre chose.
Je suppose avec un analyseur Char-By-Char comme celui-ci, vous pouvez marquer la position de la chaîne des citations de début / fin que vous puissiez rompre la chaîne par des segments de citation et ne traitez que celles qui en dehors des citations. P>
Voici un exemple de la manière dont cet analyseur devrait être suffisamment intelligent pour gérer les niveaux imbriqués. P>
Match THIS and "NOT THIS" but THIS and "NOT "THIS" or NOT THIS" but \"THIS\" is good.
//Parser "greedy" looking for nested levels
Match THIS and "
NOT THIS"
but THIS and "
NOT "
THIS"
or NOT THIS"
but \"THIS\" is good
//Parser "ungreedy" trying to close nested levels
Match THIS and " " but THIS and " " THIS " " but \"THIS\" is good.
NOT THIS NOT or NOT THIS
//Parser closing levels correctly.
Match THIS and " " but THIS and " " but \"THIS\" is good.
NOT THIS NOT " " or NOT THIS
THIS
voir Texte :: équilibré pour Perl et le Perl FAQ . P>
Cela ressemble à ce que je pourrais rechercher - mais j'espérais quelque chose que je pourrais utiliser dans PHP ...
Comme Alan M a signalé, vous pouvez utiliser Regex pour rechercher un nombre impair, vous informant ainsi de votre position à l'intérieur ou à l'extérieur de toute chaîne donnée. Prenant l'exemple de citations, nous semblons vraiment proches d'une solution à ce problème. La seule chose qui reste est de gérer des citations échappées. (Je suis certain que des citations imbriquées sont presque impossibles).
J'ai développé ma réponse pour faire face aux citations évasées.
Cela dépend du type de regex que vous utilisez - qu'il permette ou non un lookahead positif / négatif / derrière
J'avais supposé des capacités complètes de regex comme PHP, Perl, etc ...