2012-06-14 20 views
8

Estoy buscando coincidir con una cadena "Ordenar por XXX" donde XXX puede ser cualquier letra, número, punto, coma, espacio o corchete. Sin embargo, solo me gustaría hacer coincidir esto si es no rodeado de paréntesis (entre paréntesis está bien, siempre y cuando no en ambos lados). Por lo tanto, debe coincidir con la parte en cursiva de "", por lo que no debe coincidir con cualquier cosa enCoincidir cadena con Regex siempre que no esté entre paréntesis

debe coincidir (sección emparejado en cursiva):

  • Seleccione X de Y fin por z
  • seleccione y = (SELECT tOP 1 Z de C Ordenar por [ID] desc)

en caso de no coincidir:

  • Select X de Y (orden por z)
  • Select aa, NTILE (4) OVER (Ordenar por ab) grupo de AC

tengo la cadena de expresiones regulares para hacer coincidir el orden de texto: [ ]*order by [\w,.\[\] ]+. Sin embargo, estoy teniendo algunos problemas para lograr un buen resultado/detrás del trabajo. ¿Algún consejo sobre cómo proceder?

+2

No puedo diferenciar entre '(seleccione arriba 1 Z de C Ordene por [ID] desc)' y '(OVER ordene por a.b)' solo con sus criterios. – nhahtdh

+0

@nhahtdh - yup. extravió el paren en el segundo ejemplo. Editado –

+0

No me gustan las expresiones regulares. Acabo de usar algunos muy triviales hasta ahora. Encontré una herramienta para que pueda verificar sus expresiones regulares. Tal vez pueda ayudarte también. aquí está el enlace http://www.asterworld.com/en/soft/010.html –

Respuesta

1

Prueba esto:

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

Cuando se ensaya de 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

Lo suficientemente cerca para cumplir mis propósitos, por lo que estoy de acuerdo. Sin embargo, esto no coincide con 'Seleccionar aa, NTILE (4) OVER (Ordene por ab group by ac', cuando según la pregunta esto debe coincidir (abriendo paren sin un par de cierre coincidente). –

+0

Gracias, Yaakov. Voy a pensar en ese último 20%. :-) –

0

Esto funciona para mí, que me haga saber si hay otros casos me falta:
Regex r = new Regex(@"[^(](order by [^)]+)", RegexOptions.IgnoreCase);

+0

la clase de caracteres en el frente coincide con cualquier cosa que no sea un paréntesis de apertura. Por lo tanto, si lo ejecuta contra el grupo 'Seleccionar a.a, NTILE (4) OVER (Ordenar por a.b) por a.c', funciona (no coincide). Sin embargo, si lo ejecuta contra 'Seleccionar aa, NTILE (4) OVER Order by ab) group by ac' (quitando la paren de apertura antes de" Order ") entonces coincide con" R OVER Order by ab "- ya que la R de "Over" es un personaje que no es un paren abierto. –

+0

Parece que esto coincidirá con el caso que el OP dijo NO debe coincidir. – nhahtdh

+0

Tal vez me equivoqué, pero ¿qué pasa con una expresión regular de pasos múltiples: No aceptar en @ "(ordenar por [^)] +) OR @" [^ (] (ordenar por. +) O @ "[^ (] (ordenar por [^)] +). De esta forma detectamos todos los casos de paréntesis faltantes. – user1456460

-1

puede usar la alternancia de esta manera:

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

"ordenar por XXX" sería capturado por el primero o el segundo paréntesis de captura.

+0

El punto es que cuando está rodeado por paréntesis, ** no ** quiero que coincida. –

+0

solo debe coincidir si solo está rodeado por paréntesis en un lado u otro, pero no en ambos. – Jack

Cuestiones relacionadas