2009-05-15 8 views
34

Después de recoger la entrada del usuario para varias condiciones comoCombinar Regexp

  1. Empieza por: /(^@)/
  2. termina con: /(@$)/
  3. Contiene: /@/
  4. ¿No contiene

Para hacer una sola expresión regular si el usuario ingresa múltiples condiciones, Combino con lo que si "|" 1 y 2 dados que se convierta en /(^@)|(@$)/

Este método funciona hasta ahora, pero,

No soy capaz de determinar correctamente, ¿Cuál debe ser la expresión regular para 4 la condición? ¿Y combinar expresiones regulares de esta manera funciona?


Actualización: @ (entrada del usuario) no será igual por dos condiciones, y no todas las cuatro condiciones siempre presente, pero que puede ser y en el futuro puede ser que necesite más condiciones como "es exactamente "y" es exactamente no "etc. así que, soy más curioso para saber que este enfoque se escalará?

También puede haber problemas de la entrada del usuario de limpieza por lo que la expresión regular se escapó correctamente, pero que se ignora en este momento.

+0

Actualización: El propósito de combinar expresiones regulares es reducir si las condiciones son únicas. Porque esta expresión regular coincidirá con un gran número de cadenas. – nexneo

+1

¿qué quiere decir con "no contiene"? – sarsnake

+0

si la entrada de los usuarios es "cool" y la cadena no contiene esa palabra significa que coincide. – nexneo

Respuesta

62

¿Las condiciones se ORed o Y juntas?

Starts with: abc 
Ends with: xyz 
Contains: 123 
Doesn't contain: 456

La versión de OR es bastante simple; como dijiste, es principalmente una cuestión de insertar tuberías entre condiciones individuales. La expresión regular simplemente deja de buscar una coincidencia tan pronto como una de las alternativas coincida.

/^abc|xyz$|123|^(?:(?!456).)*$/ 

Esa cuarta alternativa puede parecer extraño, pero así es como se expresan "no contiene" en una expresión regular. Por cierto, el orden de las alternativas no importa; esto es efectivamente el mismo regex:

/xyz$|^(?:(?!456).)*$|123|^abc/ 

La versión AND es más complicada. Después de que cada expresión regular individual coincida, la posición del partido debe restablecerse a cero para que la próxima expresión regular tenga acceso a toda la entrada. Eso significa que todas las condiciones deben expresarse como lookaheads (técnicamente, uno de ellos no tiene que ser un vistazo, creo que expresa la intención más claramente de esta manera). Una final .*$ consuma el partido.

/^(?=^abc)(?=.*xyz$)(?=.*123)(?=^(?:(?!456).)*$).*$/ 

Y luego está la posibilidad de combinar las condiciones AND y OR - ahí es donde comienza la verdadera diversión. : D

+2

Sí, estoy bien con OR ahora. Pero gracias por poner Y versión. Combinar AND y OR no es para mí. :) – nexneo

+1

Probé la última Y expresiones regulares y noté que tiene un error de sintaxis, un ")" extra al final. Quité este caracter pero la expresión regular no pareció funcionar como estaba previsto, ¿no estoy seguro de lo que hice mal? Estoy usando .Net para probar. –

+0

Es en realidad el penúltimo ')' que no pertenece allí. Una vez que se soluciona, la razón por la que no funciona es porque no hay nada en ella que consuma caracteres: todo es lookaheads. Podría hacer que la última parte no sea una anticipación, pero para mayor claridad, preferiría agregar '. *' Al final. Lo estoy arreglando ahora; gracias por llamar mi atención. –

3

No contiene @:/(^ [^ @] * $)/

combinación funciona si el resultado previsto de combinación es que alguno de ellos resulta en todo el juego a juego expresión regular.

2

Si una cadena no debe contener @, cada personaje tiene que ser otro carácter que @:

/^[^@]*$/ 

Esto coincidirá con cualquier cadena de cualquier longitud que no contiene @.

Otra posible solución sería invertir el resultado booleano de /@/.

2

En mi experiencia con expresiones regulares, realmente necesita enfocarse en lo que EXACTAMENTE está tratando de hacer coincidir, en lugar de lo que NO debe hacer.

por ejemplo \ d {2}

[1-9] [0-9]

La primera expresión coincidirá con cualquier 2 dígitos .... y el segundo coincidirá con 1 dígito de 1 a 9 y 1 dígito - cualquier dígito. Entonces, si escribe 07, la primera expresión lo validará, pero el segundo no.

ver esto por referencia avanzada:

http://www.regular-expressions.info/refadv.html

Editado:

^((?!my string).)*$ es la expresión regular para no contiene "mi cadena".

+0

Puede dar más detalles sobre cómo la condición "No contiene" coincide con la sugerencia anterior. – nexneo

+1

Supongo que quieres una expresión que "no contenga" algo (no está claro lo que deseas que contenga la expresión). Mi sugerencia muestra cómo lo haría si no desea que la expresión contenga un dígito 0 en la primera posición, en cuyo caso limitaría el dígito de la primera posición a 1-9. No está muy claro a qué te refieres con "no contiene". No contiene qué? Por favor aclare para que podamos ayudarlo. Mi respuesta fue más bien una respuesta general.Lo siento si eso no te ayudó. – sarsnake

+0

gnomixa, las pruebas de bit muestran que su versión funciona bien. – nexneo

1

La combinación de la expresión regular para la cuarta opción con cualquiera de las otras no funciona dentro de una expresión regular. 4 + 1 significa que la cadena comienza con @ o no contiene @ en absoluto. Necesitarás dos comparaciones separadas para hacer eso.

+0

@ no será el mismo para dos condiciones y no las cuatro condiciones siempre presentes pero pueden ser y en el futuro podría necesitar más condiciones como "es exactamente" y "no es exactamente así", etc. , Tengo más curiosidad por saber que este enfoque se escalará? – nexneo

2

1 + 2 + 4 condiciones: pone en marcha | extremos, pero no en el medio

/^@[^@]*@?$|^@?[^@]*@$/ 

es casi el mismo que:

/^@?[^@]*@?$/ 

pero éste coincide con cualquier cadena sin @ , muestra 'mi nombre es hal9000'