2012-03-21 24 views
65

Aquí es una expresión regular que he creado para utilizar en JavaScript:¿Cuál es la diferencia entre corchetes y paréntesis en una expresión regular?

var reg_num = /^(7|8|9)\d{9}$/ 

Aquí es otra sugerida por mi miembro del equipo.

var reg_num = /^[7|8|9][\d]{9}$/ 

La regla es para validar un número de teléfono:

  • Debe ser de sólo diez números.
  • El primer número se supone que es cualquiera de 7, 8 o 9.
+13

Su miembro del equipo debe leer un tutorial básico de expresiones regulares. El segundo par de corchetes es superfluo, y el '|' es incorrecto, esa regex validará la cadena '" | 123456789 ''. –

+0

'[\ d]' también es ridículo, use '\ d' directamente. porque '\ d' es la abreviatura de' [1234567890] '' – Eddy

Respuesta

74

Estas expresiones regulares son equivalentes (para fines de juego):

  • /^(7|8|9)\d{9}$/
  • /^[789]\d{9}$/
  • /^[7-9]\d{9}$/

La explicación:

  • (a|b|c) es una expresión regular "OR" y significa "A o B o C", aunque la presencia de soportes, necesario para el OR, también capturas el dígito. Para ser estrictamente equivalente, codificaría (?:7|8|9) para convertirlo en no grupo de captura.

  • [abc] es una "clase de caracteres" que significa "cualquier carácter de a, b o c" (una clase de caracteres puede utilizar rangos, por ejemplo [a-d] = [abcd])

La razón de estas expresiones regulares son similares es que una clase de personaje es una abreviatura de "o" (pero solo para caracteres individuales). En una alternancia, también puede hacer algo como (abc|def) que no se traduce en una clase de caracteres.

+24

(7 | 8 | 9) 'y' [789] 'no son equivalentes, ya que la primera es la captura, el último no. '(?: 7 | 8 | 9)' sería equivalente por otro lado (supongo que lo sabes, por supuesto ...). – hochl

+0

que estoy viendo esta expresión regular: '[<<|>> | \] \] | \ [\ [] '. Debido al contexto, sé que Regex está intentando hacer coincidir '<<' or '>>' o '[[' o ']]'. Pero por lo que has dicho, debería coincidir con '<' or '>' o '[' o ']'. Si usa '|' entre '[]', ¿los corchetes se comportan de manera diferente? –

+1

@DanielKaplan no usan '|' dentro de un class' carácter [...] ', a menos que desee para que coincida con el propio carácter de barra vertical. También la duplicación de caracteres en una clase de caracteres no tiene ningún efecto: una clase de caracteres es una lista de caracteres y coincidirá exactamente con uno de ellos. Mi conjetura es que desea un grupo * *, que utiliza paréntesis normales: '(<<|>> | \] \] | \ [\ [)' – Bohemian

8

Los primeros 2 ejemplos actúan de manera muy diferente si los REEMPLAZA por algo. Si coincide en esto:

str = str.replace(/^(7|8|9)/ig,''); 

, reemplazará 7, 8 o 9 por la cadena vacía.

Si coinciden en este

str = str.replace(/^[7|8|9]/ig,''); 

va a sustituir o 78 o 9 O la barra vertical !!!! por la cuerda vacía.

Acabo de enterarme de esta manera.

+3

Bienvenido al SO! Reemplazar o emparejar, es simplemente incorrecto. Mucha gente comete ese error, y generalmente se salvan con la suya - por años, a veces - porque sus cadenas de entrada nunca contienen una tubería ('|'). –

40

El consejo de su equipo es casi correcto, excepto por el error que cometió. Una vez que descubres por qué, nunca lo olvidarás. Eche un vistazo a este error.

/^(7|8|9)\d{9}$/ 

Lo que esto hace:

  • ^ y $ denota partidos anclados, que afirma que el subpatrón entre estos anclajes son todo el partido. La cadena solo coincidirá si el subpatrón coincide con la totalidad, no solo con una sección.
  • () denota un grupo de captura.
  • 7|8|9 indica coincidencia cualquiera de 7, 8 o 9. Hace esto con alternancias, que es lo que hace el operador de tubería | - alternando entre las alternancias. Esto retrocede entre las alternancias: si la primera alternancia no coincide, el motor debe regresar antes de que la ubicación del puntero se mueva durante la coincidencia de la alternancia, para continuar coincidiendo con la siguiente alternancia; Mientras que la clase de caracteres puede avanzar secuencialmente. ver este partido en un motor de expresiones regulares con optimizaciones para minusválidos:
Pattern: (r|f)at 
Match string: carat 

alternations

Pattern: [rf]at 
Match string: carat 

class

  • \d{9} partidos nueve dígitos. \d es un metacaracter de shorthanded, que coincide con cualquier dígito.
/^[7|8|9][\d]{9}$/ 

Mira lo que hace:

  • ^ y $ denota partidos anclados también.
  • [7|8|9] es un clase de carácter. Se pueden combinar todos los caracteres de la lista 7, |, 8, | o 9, por lo que se agregó incorrectamente el |. Esto coincide sin retroceder.
  • [\d] es una clase de caracteres que habita el metacarácter \d. La combinación del uso de una clase de caracteres y un metacarácter único es una mala idea, por cierto, ya que la capa de abstracción puede ralentizar la coincidencia, pero esto es solo un detalle de implementación y solo se aplica a algunas implementaciones de expresiones regulares. JavaScript no es uno, pero hace que el subpatrón sea un poco más largo.
  • {9} indica que la única construcción anterior se repite nueve veces en total.

La expresión regular es óptima /^[789]\d{9}$/, porque /^(7|8|9)\d{9}$/ captura innecesariamente que impone una disminución del rendimiento en la mayoría de las implementaciones de expresiones regulares ( pasa a ser uno, teniendo en cuenta la cuestión utiliza la palabra clave var en el código, esto probablemente es JavaScript). El uso de que se ejecuta en PCRE para la coincidencia preg optimizará distancia la falta de marcha atrás, sin embargo no estamos en PHP, ya sea, por lo que el uso de clases [] en lugar de alternancias | da bono de desempeño que el partido no dar marcha atrás, y por lo tanto ambos partidos y falla más rápido que usar tu expresión regular anterior.

+1

solo por interés, ¿de qué programa es esa captura de pantalla? –

+5

http://regex101.com – Unihedron

Cuestiones relacionadas