2012-06-14 30 views
8

Sto cercando di abbinare una stringa "Ordina per XXX" dove XXX può essere qualsiasi lettera, numero, punto, virgola, spazio o parentesi quadra. Tuttavia, mi piacerebbe solo abbinare questo se è non circondato da parentesi (parentesi su un lato è ok, purché non su entrambi i lati). Così dovrebbe corrispondere la parte in corsivo da "", da essa non dovrebbe corrispondere nulla inCorrispondenza stringa con Regex purché non sia racchiusa tra parentesi

dovrebbe corrispondere (sezione abbinato in corsivo):

  • Selezionare X da Y ordine da z
  • selezionare y = (select top 1 Z da C Ordina per [ID] disc)

caso non corrispondere:

  • Selezionare X da Y (ordine da z)
  • Select aa, NTILE (4) OVER (ordine da ab) gruppo da ac

ho la stringa regex per abbinare l'ordine dal testo: [ ]*order by [\w,.\[\] ]+. Tuttavia, sto avendo qualche problema a ottenere il lookahead/dietro il lavoro correttamente. Qualche consiglio su come procedere?

+2

Non riesco a distinguere tra '(selezionare top 1 Z da C Order by [ID] desc)' e '(OVER Order by a.b)' con i soli criteri. – nhahtdh

+0

@nhahtdh - sì. riposto il paren nel secondo esempio. Modificato. –

+0

Non ho molte espressioni regolari. Ho appena usato alcuni molto banali fino ad ora. Ho trovato uno strumento che puoi controllare le tue espressioni regolari. Forse può aiutarti anche tu. ecco il link http://www.asterworld.com/en/soft/010.html –

risposta

1

Prova questa:

(?<!\(\s*)order\s+by\s+[\w,.\[\] ]+(?<!\s*\)) 

Nelle prove effettuate in PowerShell:

PS> @(
    'Select X from Y order by z' 
    'Select y = (select top 1 Z from C Order by [ID] desc)' 
    'Select X from Y (order by z)' 
    'Select a.a, NTILE(4) OVER (Order by a.b) group by a.c' 
    'Order by 87' 
    '(Order by 87)' 
    '(Order by 87)' 
    '(Order by 87)' 
    '(Order by 87)' 
    'Order by _foo' 
) -match '(?<!\(\s*)order\s+by\s+[\w,.\[\] ]+(?<!\s*\))' 

Select X from Y order by z 
Select y = (select top 1 Z from C Order by [ID] desc) 
Order by 87 
Order by _foo 

PS> 
+0

Abbastanza vicino per servire i miei scopi quindi accetto. Tuttavia, ciò non corrisponde a 'Select aa, NTILE (4) OVER (Ordinare per ab gruppo per ac', se in base alla domanda questa deve corrispondere (apertura del paren senza un paren di chiusura corrispondente). –

+0

Grazie, Yaakov. Ci penserò su quell'ultimo 20%. :-) –

0

Questo funziona per me, fatemi sapere se ci sono altri casi mi manca:
Regex r = new Regex(@"[^(](order by [^)]+)", RegexOptions.IgnoreCase);

+0

la classe di caratteri nella parte anteriore corrisponde a tutto ciò che non è una parentesi aperta. Quindi, se lo si esegue contro 'Select a.a, NTILE (4) OVER (Ordina da a.b) gruppo da a.c' funziona (non corrisponde). Tuttavia, se lo si esegue con 'Select aa, NTILE (4) OVER Order di ab) group by ac' (rimuovendo il paren di apertura prima di" Order "), allora corrisponde a" R OVER Order by ab "- poiché la R di "Over" è un personaggio che non è un paren aperto. –

+0

Sembra che questo corrisponderà al caso che l'OP ha detto NON dovrebbe corrispondere. – nhahtdh

+0

Forse ho sbagliato, ma per quanto riguarda la regex multi-step: Non accettare su @ "(ordine di [^)] +) O @" [^ (] (ordina per. +) OR @ "[^ (] (ordine di [^)] +). In questo modo vengono rilevati tutti i casi di parentesi mancante. – user1456460

-1

è possibile utilizzare alternanza come questa:

\(?(order by [a-z0-9., \[\]]+)(?![a-z0-9., \[\]])(?<!\))|[^(](order by [a-z0-9., \[\]]+)\) 

"order by XXX" verrebbe catturato dalla prima o dalla seconda parentesi di acquisizione.

+0

Il punto è che quando è circondato da parentesi, io ** non lo voglio **. –

+0

deve corrispondere solo se è circondato solo da parentesi su un lato o sull'altro ma non su entrambi. – Jack

Problemi correlati