2009-11-30 7 views
0

J'essaye actuellement d'écrire un RegexReplace pour m'assurer qu'une entrée peut être utilisée comme balise XML valide, ce qui signifie: pas d'espaces, pas de caractères spéciaux, seulement des minuscules, etc. ...Regex pour reformater une chaîne en une balise xml sécurisée

Y a-t-il une approche commune à cela ou dois-je tout faire à partir de zéro?

Exemple:

string Invalid = "asd(%4 asKUd n!%mn &§a_As1"; // Invalid as a tag 

string Valid = FormatToSafeXmlTag(Invalid); // How to write this function? 

// Valid = "asd4_askud_nmna_as1" 
+0

Vous pouvez vérifier si un analyseur XML peut lire la chaîne ... – Franz

+1

@Welbog - Ceci est un cas beaucoup plus petite que cela, et regex fonctionnerait probablement bien. Si je lis bien la question, il valide simplement que quelque chose serait un nom de marque valide. C'est un problème beaucoup plus petit que de voir si quelque chose est valide. Les règles pour un nom de tag valide sont probablement simples. – Herms

+2

Il n'essaye pas d'analyser xml avec regex - essayant juste de valider l'entrée d'utilisateur pour l'employer comme étiquette de xml. Cela me semble une utilisation valide pour regex. – Amarghosh

Répondre

6

Selon le XML specification, le nom d'un élément est formé de la façon suivante:

Name ::= NameStartChar (NameChar)* 

NameStartChar ::= ":" | [A-Z] | "_" | [a-z] | [#xC0-#xD6] | [#xD8-#xF6] 
    | [#xF8-#x2FF] | [#x370-#x37D] | [#x37F-#x1FFF] | [#x200C-#x200D] 
    | [#x2070-#x218F] | [#x2C00-#x2FEF] | [#x3001-#xD7FF] | [#xF900-#xFDCF] 
    | [#xFDF0-#xFFFD] | [#x10000-#xEFFFF] 
NameChar  ::= NameStartChar | "-" | "." | [0-9] | #xB7 
    | [#x0300-#x036F] | [#x203F-#x2040] 

Ce qui est trivial de convertir une expression régulière.

Si vous souhaitez supprimer un caractère en dehors de cette définition, il suffit d'inverser les caractères recherchés.

2
  • Seuls les minuscules: ^[a-z]+$
  • minuscules premier char, (en option) restant caractères lowecase/numéros ^[a-z][a-z0-9]*$
  • Seulement en majuscules: ^[A-Z]+$
  • alphabet premier char, (facultatif) caractères restants alphanumériques ^[a-zA-Z][a-zA-Z0-9]*$

EDIT: Pour couper tout sauf caractères minuscules en javascript:

str = str.replace(/[^a-z]/g, ""); 

Le hic est lorsque les utilisateurs entre dans rien d'autre que des caractères inacceptables - vous finirez par essayer de créer une balise XML avec une chaîne vide. Je demanderais plutôt à l'utilisateur d'essayer à nouveau - combien il peut être difficile d'entrer une chaîne en minuscule?

ATTENTION: Un autre cas limite est lorsque l'utilisateur entre xml ou n'importe quelle variante insensible à la casse (grâce à la réponse de @ Tim). Si vous utilisez javascript, vous ne pouvez pas utiliser la solution suggérée par Tim, car elle utilise lookbehind, une fonctionnalité non prise en charge par la regex javascript.

code JavaScript:

str = str.replace(/\s/g, "_"); //replaces spaces 

str = str.replace(/[^a-zA-Z0-9_\-]/g, "");//trim symbols 

var reg = new RegExp(/^xml/i); 

if(str.length == 0 || reg.test(str)) //is it empty or "xml" or "XmL" or .. 
    alert("invalid regex"); 
+0

tags OK? (Vos deuxième et dernier exemples ne correspondront qu'aux tags avec plusieurs caractères) – Dexter

+0

@Dexter vous l'avez repéré pendant que je l'éditais – Amarghosh

+0

@ ApoY2k Et si l'utilisateur ne saisit que des caractères non valides? – Amarghosh

2

balises XML (je suppose que vous vous posez sur les noms de tag) doivent suivre les règles suivantes:

  • commencant par, point, du côlon ou de soulignement
  • contiennent uniquement des lettres, des chiffres, point, trait de soulignement ou du côlon (pour namespaces)
  • ne doit pas commencer par xml

par conséquent, une expression régulière pour les noms de balises valides pourrait être:

^(?!xml)[\w.:][\w\d.:]*$ 

en fonction de votre saveur regex (par exemple,.NET inclut les lettres Unicode au \w, comme cela est légal pour un nom de tag). Vous pouvez également utiliser

^(?!xml)[p\{L}._:][\p{L}\p{N}._:]*$ 

si \w ne contient pas de lettres Unicode. Mais, bien sûr, vous pouvez utiliser des règles plus restrictives, et peut-être que tous les analyseurs XML ne peuvent pas gérer les noms de balises Unicode complets. Donc à la fin,

^(?!xml)[A-Za-z._:][A-Za-z0-9._:]*$ 

pourrait être votre meilleur pari ...

+0

où est-ce que vous obtenez qu'il ne doit pas commencer par "xml"? Je ne pense pas que ce soit dans la spécification.Voir la réponse de Welbog – harschware

+1

Je l'ai lu ici: http://de.selfhtml.org/xml/dtd /bearbeitungsregeln.htm#namen (désolé, c'est en allemand) où il est dit que 'xml' est réservé pour les extensions ultérieures de la norme –

+0

AFAIK, les balises' xml' sont réservées pour, bien .. xml-speci balises fic ^^ –

Questions connexes