2017-05-01 7 views
0

Ich versuche, mehrere Übereinstimmungen von überlappenden Zeichenfolgen mit Wortgrenzen zu finden. Sobald ein Teilstring gefunden wurde, wird er für eine zukünftige Übereinstimmung nicht berücksichtigt, dh die nächste Suche beginnt nach dem Ende dieses Teilstrings. Zum Beispiel benötige ich diese Entsprechungen für diese Zeichenkette:mehrere Übereinstimmungen von überlappenden Teilzeichenfolgen finden

pattern: "ab ab" 
string: "ab ab abxxxab ab ab" 
     -----   ----- 
        ^ignore this, since it is not a word boundary 
substr found: (0 4) 
substr found: (14 18) 

Ich habe den folgenden Code geschrieben, aber er findet nur den ersten Teilstring. Das Problem ist, dass nach dem Zurückweisen der 2. Übereinstimmung (aufgrund der Wortgrenze) die 3. Übereinstimmung nicht gefunden wird, was eine legale Teilkette wäre.

Der Ausgang ich erhalte, ist die folgende:

string is 0 18<ab ab abxxxab ab ab> 
    match found:start=0 end=4 
     substr found: (0 4) 
string is 5 18<ab ab abxxxab ab ab> 
    match found:start=0 end=4 
    match found:start=11 end=15 

(1), wie das Problem in diesem regex zu beheben, so dass das dritte Spiel auch in Betracht gezogen wird? (2) Ich behandle die Wortgrenzenprüfung mit explizitem C-Code, kann dies als Teil der Regex selbst geschehen?

#include <iostream> 
#include <string> 
#include <regex> 
using namespace std; 
int find_substr(string str, regex pat, int start) { 
     int last = str.length() - 1; 
    printf("string is %d %d<%s>\n", start, last, str.c_str()); 
    for(auto it = sregex_iterator(str.begin(), str.end(), pat); 
      it != sregex_iterator(); ++it) { 
     int idx = it->position(); 
     int end = idx+ it->length() - 1; 
     printf("match found:start=%d end=%d\n", idx, end); 
     if(idx<start) { 
      continue; //ignore matches before the start index 
     } 
     if(idx>0) { 
      if((str.at(idx-1)>='a' && str.at(idx-1)<='z') || 
         (str.at(idx-1)>='A' && str.at(idx-1)<='Z')) { 
       continue; // not a word boundary, ignore 
      } 
     } 
     if(end<last) { 
      if((str.at(end+1)>='a' && str.at(end+1)<='z') || 
         (str.at(end+1)>='A' && str.at(end+1)<='Z')) { 
       continue; // not a word boundary, ignore 
      } 
     } 
     printf("substr found: (%d %d)\n", idx, end); 
     return end+1; 
    } 
    return -1; 
} 
int main() { 
    string str; 
    regex pat; 
    int next; 
    str = "ab ab abxxxab ab ab"; 
    pat = "ab ab"; 
    next = find_substr(str, pat, 0); 
    if(next>0 && next<str.length()) { 
     find_substr(str, pat, next); 
    } 
} 

Antwort

1

Ist das wonach Sie suchen? \bab ab\b.

https://regex101.com/r/DtjGrN/1

Dies könnte Erhöhung erfordern (?), Da ich weiß nicht, ob die Standard-regex-Bibliothek in C++ \b unterstützt.

+0

Nein, das funktioniert nicht. Im selben Code habe ich gerade pat = "\ bab ab \ b" geändert. Kein einziges Spiel gefunden. Ich suche eine Lösung ohne Boost bitte. – R71

+0

Entschuldigung, für den vorherigen Kommentar. Es klappt. Ich habe mich in "\\ bab ab \\ b" geändert. Es funktioniert ohne Boost. – R71

Verwandte Themen