2008-11-26 5 views
1

Je cherche une expression régulière qui correspondra à toutes les chaînes SAUF celles qui contiennent une certaine chaîne à l'intérieur. Quelqu'un peut-il m'aider à le construire? Par exemple, si vous cherchez toutes les chaînes qui ont , vous n'avez pas dans l'ordre, a, b et c.Regex pour faire correspondre "tout sauf" une chaîne

Alors
abasfaf3 correspondrait, alors que
asasdfbasc ne

+0

quel moteur utilisez-vous? – Loki

+0

Tout, à la recherche d'une expression régulière générale qui peut être adaptée à n'importe quel moteur. Je cherchais vraiment une réponse théorique. – Ray

Répondre

2

en Perl:

if($str !~ /a.*?b.*?.*c/g) 
{ 
    print "match"; 
} 

devrait fonctionner.

+0

Je vois, si activement à la recherche de chaînes qui correspondent à ce que j'essaie d'éviter, puis prendre le contraire. Je ne peux pas penser à pourquoi cela ne fonctionnerait pas ... – Ray

+0

Eh bien, vous pouvez théoriquement construire une regex qui correspond à l'opposé. mais cette regex serait énorme. La façon dont vous le faites est de construire un FSM, inverser les conditions de fin, puis en construire une regex –

+0

@Ray: Oui, vous l'avez.Dans ce cas, il est plus facile de regex ce que vous ne voulez pas, puis trouvez les chaînes qui ne correspondent pas à la regex. – Alan

0

en Java:

(?m)^a?(.(?!a[^b\r\n]*b[^\r\nc]*c))+$ 

ne correspond

abasfaf3 
xxxabasfaf3 

ne correspond pas à

asasdfbascf 
xxxxasasdfbascf 
4

En Python:

>>> r = re.compile("(?!^.*a.*b.*c.*$)") 
>>> r.match("abc") 
>>> r.match("xxabcxx") 
>>> r.match("ab ") 
<_sre.SRE_Match object at 0xb7bee288> 
>>> r.match("abasfaf3") 
<_sre.SRE_Match object at 0xb7bee288> 
>>> r.match("asasdfbasc") 
>>> 
+0

Pourquoi le downvote? –

+0

Je ne vous ai pas downvote. mais j'ai demandé la même chose aujourd'hui. pourquoi ont-ils downvote mon puzzle soigné ?? –

+0

En fait, en Perl cela ne fonctionne pas. Soupir.. –

1

Eh bien, vous pouvez théoriquement construire une regex qui correspond à l'opposé. Mais pour des chaînes plus longues, cette regex deviendrait grande. La façon dont vous le faire est systématiquement (très simplifié):

  • Convertir l'expression régulière dans un automate fini déterministe
  • Convertir les conditions de fin de l'automate, de sorte qu'il accepte la langue régulière inversée
  • Convertissez l'automate en une expression régulière en supprimant successivement les nœuds de l'automate, tout en conservant le même comportement. La suppression d'un nœud nécessitera la mise en place de deux ou plusieurs expressions régulières, de manière à rendre compte du nœud supprimé.
  • Si vous avez un noeud de début et un noeud de fin, vous avez terminé: L'expression régulière qui marque le bord entre eux est votre expression régulière recherchée.

Pratiquement, vous pouvez simplement correspondre à la chaîne que vous voulez pas avoir en elle, et inverser le résultat. Voici ce qu'il ressemblerait à awk:

echo azyxbc | awk '{ exit ($0 !~ /a.*b.*c/); }' && echo matched 

Si vous êtes intéressé à cela, je recommande le livre « Introduction à la théorie du calcul » par Michael Sipser.

Questions connexes