2010-02-05 13 views
9

Lookbehind Ich benutzeRegulärer Ausdruck Problem

(?<!value=\")##(.*)## 

String passen wie ## MyString ##, die nicht in Form ist:

<input type="text" value="##MyString##"> 

Das für die obige Form funktioniert, aber nicht dafür: (Es passt noch, passen nicht)

<input type="text" value="Here is my ##MyString## coming.."> 

ich habe versucht:

(?<!value=\").*##(.*)## 

ohne Glück. Irgendwelche Vorschläge werden sehr geschätzt.

Edit: Ich PHP preg_match bin mit() Funktion

+1

Verwenden Sie Regex nicht zum Analysieren von HTML - verwenden Sie einen HTML-Parser. http://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags/1732454#1732454 –

+1

Welche Sprache verwenden Sie? –

+0

Ich benutze PHP. –

Antwort

4

Dies ist nicht perfekt (das ist, was HTML-Parser für ist), aber es wird für die überwiegende Mehrheit der HTML-Dateien arbeiten:

(^|>)[^<>]*##[^#]*##[^<>]*(<|$) 

Die Idee ist einfach. Sie suchen nach einer Zeichenfolge außerhalb von Tags. Um außerhalb der Tags zu sein, muss die nächste vorausgehende angewinkelte Klammer geschlossen sein (oder es gibt überhaupt keine Klammer), und die nächstfolgende muss sich öffnen (oder keine). Dies setzt voraus, dass in Attributwerten keine spitzen Klammern verwendet werden.

Wenn Sie tatsächlich darauf, dass der Name des Attributs „Wert“ sein, dann können Sie passen für:

value\s*=\s*"([^\"]|\\\")*##[^#]*##([^\"]|\\\")*\" 

... und dann einfach, das Spiel negieren (!preg_match(...)).

+0

danke das ist sehr nah –

0

hier ist ein Ausgangspunkt zumindest, ist es für die gegebenen Beispiele funktioniert.

(?<!<[^>]*value="[^>"]*)##(.*)## 
+0

Warnung: preg_match(): Kompilierung fehlgeschlagen: lookbehind Behauptung ist nicht feste Länge –

+0

Es schlägt fehl mit "Kompilierung fehlgeschlagen: Lookbehind Behauptung ist nicht feste Länge bei Offset 23" Ich verwende PHP preg_match Funktion –

+0

@ Mark, ich denke, .net ist der einzige Motor, der diese Art von Lookbehind unterstützt, jetzt, wo du es erwähnst! Ich gebe zu, dass dieses Problem in jeder anderen Sprache ziemlich herausfordernd ist, mein Punkt oben war nicht speziell auf dich gerichtet, du bist in der Tat wahrscheinlich richtig, aber ich sage immer noch, dass viele Leute ohne Verständnis auf den Bandwangon springen. –

1

@OP, Sie können es einfach ohne Regex tun.

$text = '<input type="text" value=" ##MyString##">'; 
$text = str_replace(" ","",$text); 
if (strpos($text,'value="##') !==FALSE){ 
    $s = explode('value="##',$text); 
    $t = explode("##",$s[1]); 
    print "$t[0]\n"; 
} 
+0

Ich glaube, da ist zu viel Aufwand. Wenn es um 50 Zeichen geht, wird es zu viel Ressourcen verbrauchen. Und es ist nicht immer Leerzeichen vor ## MyString ##, es kann alles –

+0

sein, wenn es irgendetwas anderes als Leerzeichen vor '## Mystring ##' gibt, dann sollte es nicht stimmen, wie nach deinen Kriterien korrekt? Was die Gemeinkosten betrifft, gibt es keine Möglichkeit, das zu sagen, wenn Sie nicht einige Benchmarks machen. – ghostdog74

+0

@Dali mehr Code bedeutet nicht mehr Aufwand, diese Lösung könnte sogar in einigen Situationen schneller als die Regex und in anderen langsamer sein, wie Ghostdog74 sagt, müssen Sie es tatsächlich versuchen. –