2015-06-29 14 views
6

Ich möchte eine C++ Regex, die "Bananen" oder "Pyjamas" aber nicht "Bananas2" oder "Bananaspayjamas" oder "Banane" oder im Grunde nichts anderes als die genau zwei Wörter entspricht. Also habe ich dieses:Ganzes Wort passend mit regex.h

#include <regex.h> 
#include <stdio.h> 
int main() 
{ 
    regex_t rexp; 

    int rv = regcomp(&rexp, "\\bbananas\\b|\\bpajamas\\b", REG_EXTENDED | REG_NOSUB); 
    if (rv != 0) { 
    printf("Abandon hope, all ye who enter here\n"); 
    } 
    regmatch_t match; 
    int diditmatch = regexec(&rexp, "bananas", 1, &match, 0); 
    printf("%d %d\n", diditmatch, REG_NOMATCH); 
} 

und es gedruckt 1 1, als gäbe es kein Spiel war. Was ist passiert? Ich versuchte auch \bbananas\b|\bpajamas\b für meine Regex und das scheiterte auch.

Ich fragte Whole-word matching using regex über Std :: Regex, aber Std :: Regex ist schrecklich und langsam, also versuche ich regex.h.

+5

Ich verstehe nicht, warum das wird downvoted. Es ist eine kleine, nette, in sich abgeschlossene Frage mit kompilierendem, minimalem Code, der das Problem erklärt. Darüber hinaus hat das OP die Dokumentation zumindest oberflächlich gelesen. ** Was wollen die Leute noch?! ** –

+0

Hasser werden hassen –

+0

Ich verstehe auch nicht. Die * Frage * ist nicht schlecht. – Bathsheba

Antwort

-1

Verwenden

s == "balances" || s == "pajamas"

statt, wo s ist ein std::string.

Reguläre Ausdrücke können eine einfache Lösung überkomplizieren. Vermeiden Sie sie insbesondere, wenn Sie eine feste Übereinstimmung wünschen.

+3

"Reguläre Ausdrücke können eine einfache Lösung überkomplizieren." - Das ist jedoch normalerweise nicht der Fall.Zum Beispiel ist OP * wahrscheinlich * nicht wirklich an Bananen und Pyjamas interessiert, und dies ist ein vereinfachtes Beispiel (das besagt, ja, feste Matches sollten im Allgemeinen keine Regex rechtfertigen). –

+0

Jamie Zawinski: Manche Leute denken, wenn sie mit einem Problem konfrontiert werden: "Ich weiß, ich werde reguläre Ausdrücke verwenden." Jetzt haben sie zwei Probleme. – Bathsheba

+4

Ja, ich hasse jwz für dieses Zitat. Es ist völlig falsch und die Leute sagen es als Dogma. –

0

Konrad hat eine großartige Antwort hinterlassen, die mein Problem gelöst hat, aber irgendwie ist es verschwunden, also kann ich es nicht akzeptieren. Hier ist der Code, der das Richtige, für die Nachwelt gedruckt:

#include <regex.h> 
#include <stdio.h> 

int main() 
{ 
    regex_t rexp; 

    int rv = regcomp(&rexp, "[[:<:]]bananas[[:>:]]|[[:<:]]pajamas[[:>:]]", REG_EXTENDED | REG_NOSUB); 
    if (rv != 0) { 
    printf("Abandon hope, all ye who enter here\n"); 
    } 
    regmatch_t match; 
    int diditmatch = regexec(&rexp, "bananas", 1, &match, 0); 
    printf("%d %d\n", diditmatch, REG_NOMATCH); 
} 
+1

Konrad sagt in einem Kommentar, dass diese Konstruktion auf einem System funktioniert, aber nicht auf einem anderen, so dass es Bibliothek Implementierung erscheint abhängig. Also kein Problem, wenn es mit Ihrem System funktioniert und Sie es nicht anderswo kompilieren müssen. Wenn Sie dies tun, sollten Sie nach einem Ausdruck suchen, der besser unterstützt wird. – usr2564301

+0

'[[: <:]]' gehört nicht zum POSIX-Standard. Es scheint eine Erweiterung zu sein. Konrad hat im letzten Kommentar vor dem Löschen seines Posts gesagt (und ich habe es auch nachträglich reproduziert), diese Syntax funktioniert unter Linux nicht. – nhahtdh

+0

GNU hat mehrere [** Erweiterungen **] (http://www.gnu.org/software/grep/manual/html_node/The-Backslash-Character-and-Special-Expressions.html#The-Backslash-Character- und-Spezial-Ausdrücke) '\ <', '\>', '\ b', die hier verwendet werden können - aber da es sich um Erweiterungen handelt, funktionieren sie nur, wenn Sie eine Verknüpfung zur GNU-Bibliothek herstellen, die möglicherweise nicht auf allen Systemen verfügbar ist. – nhahtdh

1

The POSIX standard gibt weder Wortgrenze Syntax noch aussehen Hinterher und Look-Ahead-Syntax (die verwendet werden, um eine Wortgrenze zu emulieren) für beide BRE und ERE . Daher ist es nicht möglich, eine Regex mit Wortgrenzen zu schreiben, die über verschiedene POSIX-kompatible Plattformen hinweg funktioniert.

Für eine portable Lösung sollten Sie PCRE oder Boost.Regex in Betracht ziehen, wenn Sie in C++ programmieren möchten.

Sonst stecken Sie mit einer nicht tragbaren Lösung fest. Wenn Sie mit einer solchen Beschränkung in Ordnung sind, gibt es mehrere Alternativen: