--Édition-- Les réponses actuelles ont des idées utiles mais je veux quelque chose de plus complet que je peux comprendre à 100% et réutiliser ; c'est pourquoi j'ai mis une prime. De plus, les idées qui fonctionnent partout sont meilleures pour moi que la syntaxe non standard comme \K
Cette question porte sur la façon dont je peux faire correspondre un motif sauf dans certaines situations s1 s2 s3. Je donne un exemple spécifique pour montrer ce que je veux dire mais je préfère une réponse générale que je peux comprendre à 100% pour pouvoir la réutiliser dans d'autres situations.
Exemple
Je veux faire correspondre cinq chiffres en utilisant \b\d{5}\b
mais pas dans trois situations s1 s2 s3 :
s1 : Pas sur une ligne qui se termine par un point comme cette phrase.
s2 : Pas n'importe où à l'intérieur de parenthèses.
s3 : Pas à l'intérieur d'un bloc qui commence par if(
et se termine par //endif
Je sais comment résoudre l'une des situations s1 s2 s3 avec un lookahead et un lookbehind, en particulier en C# lookbehind ou \K
en PHP.
Par exemple
s1 (?m)(?!\d+.*?\.$)\d+
s3 avec C# lookbehind (?
``
s3 avec PHP \K (?:(?:if\(.*?//endif)\D*)*\K\d+
Mais le mélange de conditions ensemble me fait exploser la tête. Encore plus de mauvaises nouvelles, c'est que je pourrais avoir besoin d'ajouter d'autres conditions s4 s5 à un autre moment.
La bonne nouvelle, c'est que je me moque de savoir si je traite les fichiers en utilisant les langages les plus courants comme PHP, C#, Python ou la machine à laver de mon voisin. :) Je suis assez débutant en Python & Java mais intéressé à apprendre s'il existe une solution.
Je suis donc venu ici pour voir si quelqu'un peut penser à une recette flexible.
Les indices sont bienvenus : vous n'avez pas besoin de me donner le code complet. :)
Merci.
``
1 votes
\K
n'est pas une syntaxe spéciale en php. Veuillez élaborer et clarifier ce que vous voulez dire. Si vous voulez nous dire que vous n'avez pas besoin d'une solution "compliquée", vous devez préciser ce qui est compliqué pour vous et pourquoi.0 votes
@hakre Vous voulez dire parce que ruby l'utilise maintenant et que cela a commencé en perl?
1 votes
Non, car ce n'est pas le PCRE qui est PHP (ni Ruby). Perl est différent, cependant PCRE vise à être compatible avec Perl Regex.
0 votes
Vos exigences s2 et s3 semblent être contradictoires. s2 implique que les parenthèses sont toujours assorties et peuvent être imbriquées, mais s3 exige que le:
"if("
parenthèse ouverte soit fermée, non pas avec un")"
, mais plutôt avec un:"//endif"
? Et si pour s3 vous vouliez vraiment dire que la clause if devrait être fermée avec:"//endif)"
, alors l'exigence s3 est un sous-ensemble de s2.0 votes
@hakre Oui, je connais PCRE mais pour expliquer, la question concerne le langage de programmation... il dit
surtout en C# lookbehind ou \K en PHP
... Mais en C# lookbehind n'est pas seulement en C# c'est du .NET donc vous pouvez aussi vous plaindre je dis C# pas .NET :) Et en réponse je dis Ruby pas Onigurama c'est mauvais aussi... Y a-t-il un autre langage qui utilise PCRE? Je ne parle pas de Notepad++ ou des outils serveur, c'est une question sur l'utilisation de fonctionnalités dans un langage j'espère que l'explication est claire et désolé si cela semble incorrect0 votes
Pas du tout. Je pensais que vous aviez un problème concret que vous aviez l'intention de résoudre simplement pour le terminer, mais il n'était tout simplement pas clair pour moi que vous cherchiez une solution de programmation au problème.
0 votes
@ridgerunner Intéressant désolé laissez-moi expliquer. Le s2 ressemble à quelque chose comme
(ab 123 cd)
le s3 peut êtreif(true) {hello 111 } //endif
Vous ne pouvez pas deviner cela en raison du commentaire dans le code Quoi qu'il en soit, l'exemple n'est pas si important Merci :)0 votes
@hakre vous avez tout à fait raison ! Par exemple, la commande shell sur LAMP peut répondre à la question et utiliser
\K
. J'ai changé despecial php syntax
ànot standard syntax
Merci !0 votes
Une réponse correcte à ce problème dépend fortement du texte cible auquel vous vous comparez. Par exemple, si c'est du code C, alors vous devrez analyser entièrement le texte pour filtrer les
"chaînes de caractères citées
" et les/* commentaires sur plusieurs lignes */
qui peuvent eux-mêmes contenir les jetons que vous recherchez; Par exemple: si l'un des chiffres à cinq chiffres doit être trouvé dans la chaîne suivante:'/* if( */ 12345 ") { 67890; }" '
? Vous devez définir clairement le type de fichier auquel l'expression régulière sera appliquée, car une solution pour un type de fichier (disons, JavaScript) échouera probablement pour un autre (disons, SQL).0 votes
Ceci n'est pas de la science spatiale. Chaque fois que vous avez un mélange de structures complexes que vous voulez déplacer la position du match au-delà, surtout lorsque les rétro-vérifications ont une longueur variable, vous devez faire correspondre les mauvaises conditions. Sinon, la position du match n'avancera jamais, il n'y a pas d'autre moyen. Fondamentalement, c'est un simple
(?:s1|s2|s3)|(\\b\\d{5}\\b)
juste une vérification pour le groupe 1 sur chaque correspondance. Ma question est pourquoi @Unihedro a ouvert une nouvelle prime à ce sujet ?