2010-02-05 13 views
9

Io usoespressioni regolari lookbehind problema

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

per abbinare stringa come ## MyString ## che non è in forma di:

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

Questo funziona per il modulo di cui sopra, ma non per questo: (Corrisponde ancora, non deve corrispondere)

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

Ho provato:

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

senza fortuna. Qualsiasi suggerimento sarà profondamente apprezzato.

Edit: Sto usando PHP funzione

+1

Non utilizzare regex per analizzare HTML: utilizzare un parser HTML. http://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags/1732454#1732454 –

+1

Che lingua stai usando? –

+0

Sto usando PHP. –

risposta

4

Questo non è perfetto (che è quello che parser HTML sono per), ma funzionerà per la stragrande maggioranza dei file HTML:

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

L'idea è semplice. Stai cercando una stringa che non rientri nei tag. Per essere al di fuori dei tag, la parentesi angolare precedente più vicina deve essere chiusa (o non vi è alcuna parentesi quadra) e il più vicino deve essere aperto (o nessuno). Ciò presuppone che le parentesi angolari non vengano utilizzate nei valori degli attributi.

Se effettivamente cura che il nome dell'attributo essere "valore", allora si può abbinare a:

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

... e poi semplicemente nega il match (!preg_match(...)).

+0

grazie, questo è molto vicino –

0

qui preg_match() è un punto di partenza, almeno, funziona per gli esempi forniti.

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

Avviso: preg_match(): Compilazione non riuscita: l'asserzione lookbehind non è stata riparata lunghezza –

+0

Fallisce con "Compilazione fallita: l'asserzione lookbehind non è una lunghezza fissa all'offset 23" Uso la funzione preg_match di PHP –

+0

@ Marchio, penso .net è l'unico motore per supportare questo tipo di lookbehind ora ne parli! Ammetto che questo problema in realtà è piuttosto stimolante in qualsiasi altra lingua, il mio punto di sopra non era rivolto specificamente a te, probabilmente hai ragione proprio in questo caso, ma continuo a dire che molte persone saltano sul bandwangon senza capire. –

1

@OP, è possibile farlo semplicemente senza regex.

$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

Credo che ci sia troppo sovraccarico in questo. Quando si tratta di sostituire, diciamo 50 stringhe, consumerà troppe risorse. E non sempre gli spazi bianchi prima ## MyString ##, potrebbe essere qualsiasi cosa –

+0

se non ha spazi prima di '## Mystring ##', quindi non dovrebbe corrispondere, secondo i tuoi criteri corretti? Per quanto riguarda i costi generali, non c'è modo di dirlo a meno che non si eseguano alcuni benchmark. – ghostdog74

+0

@Dali più codice non significa più overhead, questa soluzione potrebbe anche essere più veloce di una regex in alcune situazioni e più lenta in altre, come dice ghostdog74, è necessario provarla effettivamente. –