7
votes

Expressions régulières Lookahead négatif

Je fais une gymnastique d'expression régulière. Je me suis mis sur la tâche d'essayer de rechercher le code C # où il y a une utilisation de l'AS-opérateur non suivi d'un chèque null dans une quantité raisonnable d'espace. Maintenant, je ne veux pas analyser le code C #. Par exemple. Je souhaite capturer des extraits de code tels que xxx pré>

Cependant, ne capturez pas p> xxx pré>

ni pour cette matière p> xxx PRE>

Ainsi, tout chèque null aléatoire comptera comme un "bon chèque" et donc non trouvé. p>

La question est la suivante: strong> Comment puis-je correspondre quelque chose tout en garantissant que quelque chose ne se trouve pas dans ses activités de suite. P>

J'ai essayé l'approche naïve, cherche pour 'comme' puis faire un regard négatif dans un délai de 150 caractères. P>

\bas\b.{1,150}(?!\b==\s*null\b)


3 commentaires

Vous ne pouvez pas utiliser un parseur C # approprié?


J'ai déclaré au début "Je fais des gymnastiques d'expression régulières. Je me suis mis sur la tâche d'essayer de chercher c #" ...


Est-ce comme regarder le football et penser "c'est comme faire de la gymnastique"? :-)


6 Réponses :


2
votes

Mettez le . {1,150} code> à l'intérieur du lookahead et remplacez . code> avec \ s \ s code> (en général, . code> ne correspond pas à de nouvelles lignes). En outre, le \ b code> peut être trompeur près du == code>.

\bas\b(?![\s\S]{1,150}==\s*null\b)


4 commentaires

Je ne peux pas avoir votre idée de travailler, cela inclut toujours le deuxième exemple ci-dessus dans mes résultats de la recherche.


Cette regex: \ bas \ b (?! [\ S \ s] {1 150} == \ s * null \ b) est assez proche, mais ne correspond pas à la seconde comme dans le premier set de "devrait correspondre" des données de test.


@Ridgerunner fonctionne-t-il pour vous avec Python? Je n'ai pas de configuration C # pour tester avec.


Réponse courte, oui. J'utilise Regexbuddy pour composer la plupart de mes regextes. Il émule de nombreuses saveurs de regex différents. Je viens de vérifier et oui, votre regex se comporte de même en mode Python. J'ai également écrit un script de test dans Python 3.0.1 avec les mêmes résultats. Les données de test que j'utilise sont tout le texte des trois échantillons et les deux commentaires entre; I.e. Y compris le Cependant, ne capturez pas et ni pour cette matière . Je viens de sélectionner les trois, copiés et colplés. Je viens d'ajouter les données de test que j'utilise pour ma réponse.



11
votes

Je love em> gymnastique regex! Voici un commentaire PHP REGEX:

text = r"""    var x1 = x as SimpleRes;
    var y1 = y as SimpleRes;
    if(x1.a == y1.a)

however, not capture
    var x1 = x as SimpleRes;
    var y1 = y as SimpleRes;
    if(x1 == null)

nor for that matter
    var x1 = x as SimpleRes;
    var y1 = y as SimpleRes;
    if(somethingunrelated == null) {...}
    if(x1.a == y1.a)"""


2 commentaires

Et si vous souhaitez que cela fonctionne avec un test négatif conditionnel, par exemple. x! = NULL , vous modifiez simplement chacun: == à: [! =] =


Très bien fait et bonne explication. +1. J'inclus la mise en garde habituelle sur REGEX n'étant pas 100% fiable pour l'analyse C #, cependant.



2
votes

Je pense que cela aiderait à placer le nom de la variable () afin que vous puissiez l'utiliser comme référence arrière. Quelque chose comme ce qui suit, xxx


0 commentaires

2
votes

La question n'est pas claire. Que voulez-vous exactement ? Je regrette, mais je ne comprends toujours pas, après avoir lu la question et les commentaires de nombreuses fois.

.

Doit être en C #? En python? Autre ? Il n'y a aucune indication concernant ce point

.

Voulez-vous une correspondance uniquement si un si (... == ...) ligne Un bloc de var ... = ... lignes?

ou peut être une ligne hétérogène entre le bloc et le si (... == .. .) ligne sans arrêter la correspondance?

Mon code prend la deuxième option comme vrai.

.

est un si ( ... == null) ligne après un si (... == ...) Ligne arrêter le matchin ou non?

Impossible de comprendre si C'est oui ou non, j'ai défini les deux regextes pour attraper ces deux options.

.

J'espère que mon code sera suffisamment clair et répondra à votre préoccupation.

Il est en python xxx

résultat xxx


1 commentaires

+1 Je conviens que la question est assez vague. La plupart des gens ne comprennent pas qu'une bonne question de regex doit être précisément précisément.



2
votes

Permettez-moi d'essayer de redéfinir votre problème:

  1. Recherchez une affectation "comme" - Vous avez probablement besoin d'une meilleure expression pour rechercher des missions réelles et peut vouloir stocker l'expression attribuée, mais utilisons "\ bas \ b" pour l'instant
  2. Si vous voyez un si (... == null) dans des 150 caractères, ne correspond pas à
  3. Si vous ne voyez pas un si (... == null) dans des 150 caractères, correspond à

    Votre expression \ bas \ b. {1,150} (?! \ b == \ s * null \ b) ne fonctionnera pas à cause du regard négatif. La regex peut toujours ignorer ou derrière une lettre afin d'éviter ce look négatif et que vous finissez par correspondre même lorsqu'il y a un si (... == null) là.

    Les regex ne sont vraiment pas bons à pas correspondant à quelque chose. Dans ce cas, vous préférez essayer de faire correspondre une affectation "comme" avec un chèque "if == null" dans les 150 caractères: xxx

    puis nier le chèque : si (! regex.match (texte)) ...


0 commentaires

1
votes
(?s:\b+as\b(?!.{0,150}==\s*null\b))

0 commentaires