solo regulares regular probar palabra numeros letras expresiones expresion exacta espacios espacio direccion casa blanco alfanumerico php regex validation utf-8

probar - expresiones regulares php



Regex para detectar la cadena UTF-8 no vĂ¡lida (3)

Pongo esto aquí para completar:

Suponiendo que PHP está compilado con PCRE, lo más frecuente es que también esté habilitado con UTF-8. Entonces, como se pidió explícitamente en la pregunta, esta expresión regular muy simple puede detectar cadenas UTF-8 no válidas, porque no coinciden:

preg_match(''//u'', $string);

Luego puede argumentar que el modificador de u (PCRE_UTF8) no siempre está disponible, y cierto, esto puede suceder como muestra esta pregunta:

  • ¿De qué depende la marca preg_match_all u ?

Sin embargo, en mi práctica en vivo, esto nunca fue un problema. Es más un problema que la extensión PCRE no esté disponible en absoluto, lo que haría que cualquier respuesta que contenga pcre sea inútil (incluso la mía aquí). Pero la mayoría de las veces ese problema era más un problema del pasado a partir de hoy menos algunos años.

Una respuesta más larga similar a esta se ha dado en la pregunta de alguna manera duplicada:

Así que creo que esta pregunta debería resaltar más de los beneficios con los que se envía la respuesta sugerida.

En PHP, podemos usar mb_check_encoding() para determinar si una cadena es válida en UTF-8. Pero esa no es una solución portátil, ya que requiere que la extensión mbstring esté compilada y habilitada. Además, no nos dirá qué carácter no es válido.

¿Existe una expresión regular (u otro método 100% portátil) que pueda coincidir con los bytes UTF-8 no válidos en una cadena dada? De esa manera, esos bytes se pueden reemplazar si es necesario (mantener la información binaria, como cuando se crea un archivo xml de salida de prueba que incluye datos binarios). Así que convertir los caracteres a UTF-8 perdería información. Por lo tanto, podemos querer convertir:

"foo" . chr(128) . chr(255)

Dentro

"foo<128><255>"

Así que simplemente "detectando" que la cadena no es lo suficientemente buena, deberíamos poder detectar qué caracteres no son válidos.


Puede usar esta expresión regular de PCRE para verificar si hay un UTF8 válido en una cadena. Si las expresiones regulares coinciden, la cadena contiene secuencias de bytes no válidas. Es 100% portátil porque no depende de PCRE_UTF8 para compilarlo.

$regex = ''/( [/xC0-/xC1] # Invalid UTF-8 Bytes | [/xF5-/xFF] # Invalid UTF-8 Bytes | /xE0[/x80-/x9F] # Overlong encoding of prior code point | /xF0[/x80-/x8F] # Overlong encoding of prior code point | [/xC2-/xDF](?![/x80-/xBF]) # Invalid UTF-8 Sequence Start | [/xE0-/xEF](?![/x80-/xBF]{2}) # Invalid UTF-8 Sequence Start | [/xF0-/xF4](?![/x80-/xBF]{3}) # Invalid UTF-8 Sequence Start | (?<=[/x0-/x7F/xF5-/xFF])[/x80-/xBF] # Invalid UTF-8 Sequence Middle | (?<![/xC2-/xDF]|[/xE0-/xEF]|[/xE0-/xEF][/x80-/xBF]|[/xF0-/xF4]|[/xF0-/xF4][/x80-/xBF]|[/xF0-/xF4][/x80-/xBF]{2})[/x80-/xBF] # Overlong Sequence | (?<=[/xE0-/xEF])[/x80-/xBF](?![/x80-/xBF]) # Short 3 byte sequence | (?<=[/xF0-/xF4])[/x80-/xBF](?![/x80-/xBF]{2}) # Short 4 byte sequence | (?<=[/xF0-/xF4][/x80-/xBF])[/x80-/xBF](?![/x80-/xBF]) # Short 4 byte sequence (2) )/x'';

Podemos probarlo creando algunas variaciones de texto.

// Overlong encoding of code point 0 $text = chr(0xC0) . chr(0x80); var_dump(preg_match($regex, $text)); // int(1) // Overlong encoding of 5 byte encoding $text = chr(0xF8) . chr(0x80) . chr(0x80) . chr(0x80) . chr(0x80); var_dump(preg_match($regex, $text)); // int(1) // Overlong encoding of 6 byte encoding $text = chr(0xFC) . chr(0x80) . chr(0x80) . chr(0x80) . chr(0x80) . chr(0x80); var_dump(preg_match($regex, $text)); // int(1) // High code-point without trailing characters $text = chr(0xD0) . chr(0x01); var_dump(preg_match($regex, $text)); // int(1)

etc ...

De hecho, como esto coincide con los bytes no válidos, podría usarlo en preg_replace para reemplazarlos:

preg_replace($regex, '''', $text); // Remove all invalid UTF-8 code-points


El W3C tiene una página (titulada Codificación de formulario multilingüe ) que enumera la siguiente expresión regular de Perl que coincide con una cadena UTF-8 válida .

(Tenga en cuenta que esto es lo contrario de la expresión regular indicada en otra respuesta a esta pregunta SO que coincide con una cadena UTF-8 no válida ).

# Returns true if $field is UTF-8, and false otherwise. $field =~ m//A( [/x09/x0A/x0D/x20-/x7E] # ASCII | [/xC2-/xDF][/x80-/xBF] # non-overlong 2-byte | /xE0[/xA0-/xBF][/x80-/xBF] # excluding overlongs | [/xE1-/xEC/xEE/xEF][/x80-/xBF]{2} # straight 3-byte | /xED[/x80-/x9F][/x80-/xBF] # excluding surrogates | /xF0[/x90-/xBF][/x80-/xBF]{2} # planes 1-3 | [/xF1-/xF3][/x80-/xBF]{3} # planes 4-15 | /xF4[/x80-/x8F][/x80-/xBF]{2} # plane 16 )*/z/x;