2016-02-07 12 views
5

Ho sviluppato un'espressione regolare per identificare un blocco di xml all'interno di un file di testo. L'espressione si presenta così (ho rimosso tutti fuga java barre per rendere più facile lettura):Qual è la differenza tra [ s S] *? e .*? nelle espressioni regolari di Java?

<\?xml\s+version="[\d\.]+"\s*\?>\s*<\s*rdf:RDF[^>]*>[\s\S]*?<\s*\/\s*rdf:RDF\s*> 

Poi ho ottimizzato e sostituito con [\s\S]*?.*? E improvvisamente smesso di riconoscere il codice XML.

Per quanto ne so, \s significa tutti i simboli bianco-spazio e \S significa tutti i simboli bianchi interlinea non o [^\s] così [\s\S] logicamente dovrebbe essere equivalente a . non ho usato i filtri avidi, così che cosa potrebbe essere la differenza ?

+3

Per impostazione predefinita, '.' non corrisponde ai separatori di riga.Può corrispondere a tutti i caratteri (compresi i separatori di riga) se si utilizza il flag 'Patter.DOTALL'. '[\ s \ S]' è impostato che include tutti gli spazi bianchi \ s e tutti gli spazi non bianchi \ S, che rappresentano in modo efficace tutti i caratteri (compresi i separatori di riga). – Pshemo

+0

Il finale? non contribuisce in entrambi i casi. – EJP

+0

Uno molto correlato: [* Qual è la differenza tra questi RegEx *] (http://stackoverflow.com/a/14648811/3832970) –

risposta

6

Le espressioni regex . e \s\S non sono equivalenti, poiché . non cattura i terminatori di riga (come la nuova riga) per impostazione predefinita.

Secondo il oracle website, . partite

Qualsiasi carattere (può o non può corrispondere terminatori di linea)

mentre una terminazione di linea è uno dei seguenti:

  • Un carattere di fine riga (avanzamento riga) ('\n'),
  • Un carattere di ritorno immediatamente seguito da un carattere di nuova riga ("\r\n"),
  • Un carattere autonomo ritorno a capo ('\r'),
  • Un carattere di nuova linea ('\u0085'),
  • Una linea carattere separatore ('\u2028') o
  • Un carattere separatore di paragrafo ('\u2029).

Le due espressioni non sono equivalenti, a patto che le bandiere necessari non sono impostati. Ancora una volta citando il sito oracolo:

Se è attivata la modalità UNIX_LINES, quindi gli unici terminatori di linea riconosciuti sono caratteri di nuova riga.

L'espressione regolare . corrisponde a qualsiasi carattere tranne una riga terminatore a meno che non sia specificato il flag DOTALL.

+1

Sì, questo spiegherà la differenza, grazie – Dmitry

2

Here è un foglio che spiega tutti i comandi regex.

Fondamentalmente, \s\S preleverà tutti i caratteri, incluse le nuove righe. Considerando che . non preleva i terminatori di riga per impostazione predefinita (alcuni flag devono essere impostati per essere prelevati).

+0

Sì, ogni \ è stato doppio escape. Ho rimosso le doppie barre solo per renderlo facile da leggere. L'espressione funziona, ma smette di funzionare non appena sostituisco '[\ s \ S] *?' Con '. *?' Quindi la differenza dovrebbe essere lì. – Dmitry

+0

questa è espressione reale: '<\\? Xml \\ s + versione = \" [\\ d \\.] + \ "\\ s * \\?> \\ s * <\\ s * rdf: RDF [^>] *> [\\ s \\ S] *? <\\ s * \\/\\ s * rdf: RDF \\ s *> ' – Dmitry

+0

Questo non è vero. '.' può sfuggire a nuove righe, a seconda di alcuni flag. Dai un'occhiata alla mia risposta per tutti i dettagli .. –