2012-02-17 64 views
16

Ya tengo un código de trabajo pero necesito que alguien me ayude a explicar por qué funciona si pueden.Regex para permitir solo caracteres alfanuméricos, coma, guión, guión bajo y punto y coma

Estoy usando PHP para reemplazar cualquier cosa en una cadena si no es ni az, AZ, 0-9, una coma, un punto y coma, guiones bajos o un guión (que en última instancia debería representar un nombre de usuario único, o lista separada por comas/punto y coma de nombres de usuario).

las siguientes obras:

$data = preg_replace('/[^,;a-zA-Z0-9_-]/s', '', $data); 

pero los siguientes no:

$data = preg_replace('/[^a-zA-Z0-9_-,;]/s', '', $data); 

qué hará esto sólo trabajo cuando la coma y el punto y coma son al comienzo? Ponerlos al final parece romper cosas (esto es lo que probé inicialmente cuando me encontré/[^ a-zA-Z0-9 _-]/s.

Como un lado, también estoy usando lo siguiente para recorte los arrastran punto y coma (plural) o comas (en plural) y alguien puede ser capaz de sugerir una manera más eficiente y/o elegante de hacer esto ?:

if(preg_match('/;$/', $data)) 
{ 
    $data = rtrim($data, ';'); 
} 
if(preg_match('/,$/', $data)) 
{ 
    $data = rtrim($data, ','); 
} 

Gracias por cualquier ayuda :)

Respuesta

27

No es la coma y el punto y coma los que causan su problema; es el guion Mira las partes de su clase de caracteres y considerar lo que significan:

0-9 # Anything from '0' to '9', meaning 0, 1, 2, ... 9 
A-Z # Anything from 'A' to 'Z', meaning A, B, C, ... Z 
_-, # Anything from '_' to ',', meaning...uh...hmmm. 

No hay clara progresión desde _ a ,, por lo que el motor de expresiones regulares no está seguro de qué hacer con esto. En las clases de caracteres, si quiere que un guión se interprete literalmente, tiene que ser al principio o al final de la clase (o escapado con una barra invertida). Así que cualquiera de estos funcionará:

[^,;a-zA-Z0-9_-] 
[^-,;a-zA-Z0-9_] 
[^a-zA-Z0-9_\-,;] 

En cuanto a recorte fuera de la final, se puede hacer todo esto en una expresión regular reemplazar:

$data = preg_replace('/[^,;a-zA-Z0-9_-]|[,;]$/s', '', $data); 
+0

_" No hay una progresión clara desde '_ 'to', '" _: hay una progresión muy clara: se basa en la tabla Unicode. En este caso, sin embargo, '_' viene _after_', 'en la tabla Unicode, por lo que no es posible un rango. – Xufox

+0

@Xufox - Bueno, eso sería una regresión, ¿no? ;) El punto es que no hay progresión que el motor de expresiones regulares entienda. Pero tienes razón, [aparentemente hay una progresión válida en la otra dirección] (http://rextester.com/YGC93292), de ',' a '_'. ¡No lo sabía hasta ahora, gracias! –

2

Creo que es la ubicación del guión lo que importa: tiene que ser al principio o al final para ser un guión (literal); de lo contrario, se usa para definir un rango.

+0

+1 También tenga en cuenta que usted podría simplemente utilizar una barra invertida a escapa del guión desviado en el segundo patrón y funcionará igual que el primer patrón: ''/ [^ a-zA-Z0-9 _ \ - ,;]/s'' – rdlowrey

1

se puede escapar el guión y ponerlo en cualquier lugar de la expresión regular como este \-

En cuanto a las comas finales y comas, prueba este /[,;]+$/ podría aparecer cualquier comas y punto y coma al final, incluso si son muchos.

Cuestiones relacionadas