special online characters regex unicode pcre

characters - regex online



Unicode Regex; Caracteres XML no vĂ¡lidos (5)

La lista de caracteres XML válidos es bien conocida, tal como se define en la especificación:

#x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF]

Mi pregunta es si es posible o no hacer una expresión regular PCRE para esto (o su inversa) sin codificar realmente los puntos de código, mediante el uso de categorías generales Unicode. Un inverso puede ser algo así como [/ p {Cc} / p {Cs} / p {Cn}], excepto que cubre de forma incorrecta saltos de línea y pestañas y omite algunos otros caracteres no válidos.


Intenté esto en Java y funciona:

private String filterContent(String content) { return content.replaceAll("[^//u0009//u000a//u000d//u0020-//uD7FF//uE000-//uFFFD]", ""); }

Gracias Jeff.


Las soluciones anteriores no funcionaron para mí si el código hexadecimal estaba presente en el xml. p.ej

<element>&#x8;</element>

El siguiente código se romperá:

string xmlFormat = "<element>{0}</element>"; string invalid = " &#x8;"; string xml = string.Format(xmlFormat, invalid); xml = Regex.Replace(xml, @"[/x01-/x08/x0B/x0C/x0E/x0F/u0000-/u0008/u000B/u000C/u000E-/u001F]", ""); XDocument.Parse(xml);

Vuelve:

XmlException : '''', valor hexadecimal 0x08, es un carácter no válido. Línea 1, posición 14.

La siguiente es la expresión regular mejorada y solucionó el problema mencionado anteriormente:

& # x ([0-8BCEFbcef] | 1 [0-9A-Fa-f]); | [/ x01- / x08 / x0B / x0C / x0E / x0F / u0000- / u0008 / u000B / u000C / u000E- / u001F]

Aquí hay una prueba unitaria para los primeros 300 caracteres Unicode y verifica que solo se eliminen los caracteres no válidos:

[Fact] public void validate_that_RemoveInvalidData_only_remove_all_invalid_data() { string xmlFormat = "<element>{0}</element>"; string[] allAscii = (Enumerable.Range(''/x1'', 300).Select(x => ((char)x).ToString()).ToArray()); string[] allAsciiInHexCode = (Enumerable.Range(''/x1'', 300).Select(x => "&#x" + (x).ToString("X") + ";").ToArray()); string[] allAsciiInHexCodeLoweCase = (Enumerable.Range(''/x1'', 300).Select(x => "&#x" + (x).ToString("x") + ";").ToArray()); bool hasParserError = false; IXmlSanitizer sanitizer = new XmlSanitizer(); foreach (var test in allAscii.Concat(allAsciiInHexCode).Concat(allAsciiInHexCodeLoweCase)) { bool shouldBeRemoved = false; string xml = string.Format(xmlFormat, test); try { XDocument.Parse(xml); shouldBeRemoved = false; } catch (Exception e) { if (test != "<" && test != "&") //these char are taken care of automatically by my convertor so don''t need to test. You might need to add these. { shouldBeRemoved = true; } } int xmlCurrentLength = xml.Length; int xmlLengthAfterSanitize = Regex.Replace(xml, @"&#x([0-8BCEF]|1[0-9A-F]);|[/u0000-/u0008/u000B/u000C/u000E-/u001F]", "").Length; if ((shouldBeRemoved && xmlCurrentLength == xmlLengthAfterSanitize) //it wasn''t properly Removed ||(!shouldBeRemoved && xmlCurrentLength != xmlLengthAfterSanitize)) //it was removed but shouldn''t have been { hasParserError = true; Console.WriteLine(test + xml); } } Assert.Equal(false, hasParserError); }


Otra forma de eliminar caracteres XML incorrectos en C # con el uso del método XmlConvert.IsXmlChar (disponible desde .NET Framework 4.0)

public static string RemoveInvalidXmlChars(string content) { return new string(content.Where(ch => System.Xml.XmlConvert.IsXmlChar(ch)).ToArray()); }

o puede verificar que todos los caracteres sean válidos para XML.

public static bool CheckValidXmlChars(string content) { return content.All(ch => System.Xml.XmlConvert.IsXmlChar(ch)); }

.Net Fiddle - https://dotnetfiddle.net/v1TNus

Por ejemplo, el símbolo de tabulación vertical (/ v) no es válido para XML, es válido UTF-8, pero no es válido XML 1.0, e incluso muchas bibliotecas (incluido libxml2) lo pasan por alto y emiten silenciosamente XML no válido.


Para los sistemas que almacenan internamente los puntos de código en UTF-16 , es común usar pares de sustitución (xD800-xDFFF) para los puntos de código superiores a 0xFFFF y en esos sistemas debe verificar si realmente puede usar, por ejemplo, / u12345 o debe especificar eso como un par sustituto. (Acabo de descubrir que en C # puede usar / u1234 (16 bits) y / U00001234 (32 bits) )

Según Microsoft "la recomendación del W3C no permite caracteres sustitutos dentro de los nombres de los elementos o los atributos". Mientras buscaba el sitio web de W3s, encontré C079 y C078 que podrían ser de su interés.


Sé que esta no es exactamente una respuesta a su pregunta, pero es útil tenerla aquí:

Expresión regular para hacer coincidir caracteres XML válidos :

[/u0009/u000a/u000d/u0020-/uD7FF/uE000-/uFFFD]

Entonces, para eliminar caracteres inválidos de XML, harías algo como

// filters control characters but allows only properly-formed surrogate sequences private static Regex _invalidXMLChars = new Regex( @"(?<![/uD800-/uDBFF])[/uDC00-/uDFFF]|[/uD800-/uDBFF](?![/uDC00-/uDFFF])|[/x00-/x08/x0B/x0C/x0E-/x1F/x7F-/x9F/uFEFF/uFFFE/uFFFF]", RegexOptions.Compiled); /// <summary> /// removes any unusual unicode characters that can''t be encoded into XML /// </summary> public static string RemoveInvalidXMLChars(string text) { if (string.IsNullOrEmpty(text)) return ""; return _invalidXMLChars.Replace(text, ""); }

Tuve nuestro genio regex / XML residente, el de las 4.400+ publicación actualizada , verifique esto, y él lo firmó.