pcre insensibilità del case: gestisci le sequenze di escape come byte non elaborati?

1

Considera la seguente espressione regolare (non unicode):

Example:\x04\x05\x41

Supponiamo che tu cerchi questa espressione regolare in modo insensibile. Ti aspetteresti che cerchi la finale \ x41 in modo sensibile al maiuscolo / minuscolo? Le persone che chiedo in realtà si aspettano un simile comportamento. E tali aspettative sono sbagliate.

Perldoc dice:

Note that a character expressed as one of these escapes is considered a character without special meaning by the regex engine, and will match "as is".

Il che significa che se il carattere è sfuggito è un carattere non speciale stampabile equivale semplicemente a digitare quel carattere. Ed è così che si comporta in realtà. Tuttavia, se l'espressione regolare è caratteri maiuscole e minuscole, i caratteri alfabetici hanno un significato speciale di "questo carattere o lo stesso carattere in caso contrario" e tale significato speciale non viene ignorato nelle sequenze \ x.

Le sequenze di escape hanno una semantica "byte grezzo", ma non sempre. Ti sembra un disagio nel design?

C'è un modo per far sì che pcre consideri le sequenze \ x come byte non elaborati che ignorano la distinzione tra maiuscole e minuscole? Forse come una bandiera? Come patch non standard? Se no, come se il codice del motore di pcre può essere modificato per fornire tale funzionalità?

    
posta Muxecoid 23.06.2013 - 18:47
fonte

1 risposta

2

However if regex is case insensitive alphabetic characters do have a special meaning of "this character or same character in opposite case" and such special meaning is not ignored in \x sequences.

Stai leggendo troppo in ciò che costituisce "un significato speciale". In questo caso, si riferisce a singoli caratteri che dirigono l'interpretazione dell'input come . e * . Sfuggire a quei personaggi in qualsiasi forma li considera letterali. In altre parole, . significa corrispondere a qualsiasi carattere ma \. o \x2e significa corrispondere a un periodo. (Esistono eccezioni, come \d , che va bene perché non c'è mai bisogno di sfuggire a un% in minuscolo di co_de.)

Il significato speciale non include il comportamento causato dall'uso dei modificatori. L'utilizzo di d indica al motore di utilizzare un algoritmo diverso per confrontare i singoli caratteri, cosa che avviene molto tempo dopo che l'espressione stessa è stata analizzata. L'escape i sarà stato applicato quando l'espressione stessa è stata elaborata, il che significa che \x sarà già stato interpretato come \x41 .

Escape sequences have "raw byte" semantics, but not always. Does it seem to you like a design awkwardness?

Originariamente le escaping venivano ad esistere come modo per incorporare caratteri in file che altrimenti non potevano essere rappresentati usando caratteri stampabili. Se incorporati così com'è, questi personaggi potrebbero essere interpretati come sequenze di controllo o sarebbero semplicemente invisibili quando li guardi in un editor o su una pagina stampata. Le espressioni regolari hanno cooptato questo concetto e aggiunto tutti i tipi di escape aggiuntivi che avevano un significato semantico piuttosto che letterale, come il costrutto A con il quale probabilmente hai familiarità.

Quanto è imbarazzante sarebbe una questione di opinione, ma non c'è davvero alcun modo di denotare un significato speciale nelle stringhe senza selezionare uno dei caratteri altrimenti validi per farlo.

Is there a way to cause pcre to treat \x sequences as raw bytes that ignore case sensitivity?

No, non c'è. Perl non lo consente, quindi neanche PCRE.

Le espressioni regolari Perl hanno un modo per abilitare o disabilitare i modificatori all'interno di spazi di caratteri (vedi Esteso La sezione di Patters di perlre ):

/(?i:case-insensitive)case-sensitive/
/(?-i:case-sensitive)case-insensitive/i

Se la tua espressione regolare è disponibile come stringa, potresti sviluppare una funzione che equivale a \(...\) , il che ti farebbe risparmiare la necessità di modificare PCRE.

As non standard patch? If no how if at all pcre engine code can be modified to provide such functionality?

Tutto è possibile, ma non ho intenzione di entrare in PCRE e capirlo per te. Dovresti modificare il parser RE in modo che memorizzi i valori letterali specificati con s/((?<!\)\x[[:xdigit:]]{2})/(?-i:$1)/g come intervallo sensibile al maiuscolo / minuscolo anziché a un valore letterale. Corre il rischio di rompere le espressioni che dipendono dal comportamento standard, quindi dovresti anche aggiungere un modificatore che lo abiliti esplicitamente.

A proposito, se stai semplicemente cercando una stringa all'interno di un'altra, usare \x è eccessivo. Chiamare m// sarebbe più semplice e molto più efficiente.

    
risposta data 24.06.2013 - 14:56
fonte

Leggi altre domande sui tag