2009-09-10 6 views
1

J'ai codé la fonction suivante. Mais sûrement quelqu'un a une façon plus élégante d'effectuer cette tâche.Fonction d'assainissement de l'attribut HTML Id en Java

/** 
* 
* HTML 4 Specification 
* ID and NAME tokens must begin with a letter ([A-Za-z]) and may be followed by any number 
* of letters, digits ([0-9]), hyphens ("-"), underscores ("_"), colons (":"), and periods ("."). 
* @param s 
* @return 
*/ 
public static String sanitizeHTMLIdAttribute(String s) { 
    String sanitize = ""; 
    if(s!=null) { 
    for(int i = 0; i < s.length(); i++) { 
     if(s.charAt(i) == '-' || s.charAt(i) == '_' || s.charAt(i) == ':' || 
     s.charAt(i) == '.' || s.charAt(i) == '0' || s.charAt(i) == '1' || 
     s.charAt(i) == '2' || s.charAt(i) == '3' || s.charAt(i) == '4' || 
     s.charAt(i) == '5' || s.charAt(i) == '6' || s.charAt(i) == '7' || 
     s.charAt(i) == '8' || s.charAt(i) == '9' || 
     s.charAt(i) == 'a' || s.charAt(i) == 'b' || s.charAt(i) == 'c' || 
     s.charAt(i) == 'd' || s.charAt(i) == 'e' || s.charAt(i) == 'f' || 
     s.charAt(i) == 'g' || s.charAt(i) == 'h' || s.charAt(i) == 'i' || 
     s.charAt(i) == 'j' || s.charAt(i) == 'k' || s.charAt(i) == 'l' || 
     s.charAt(i) == 'm' || s.charAt(i) == 'n' || s.charAt(i) == 'o' || 
     s.charAt(i) == 'p' || s.charAt(i) == 'q' || s.charAt(i) == 'r' || 
     s.charAt(i) == 's' || s.charAt(i) == 't' || s.charAt(i) == 'u' || 
     s.charAt(i) == 'w' || s.charAt(i) == 'x' || s.charAt(i) == 'y' || 
    s.charAt(i) == 'z' || 
     s.charAt(i) == 'A' || s.charAt(i) == 'B' || s.charAt(i) == 'C' || 
     s.charAt(i) == 'D' || s.charAt(i) == 'E' || s.charAt(i) == 'F' || 
     s.charAt(i) == 'G' || s.charAt(i) == 'H' || s.charAt(i) == 'I' || 
     s.charAt(i) == 'J' || s.charAt(i) == 'K' || s.charAt(i) == 'L' || 
     s.charAt(i) == 'M' || s.charAt(i) == 'N' || s.charAt(i) == 'O' || 
     s.charAt(i) == 'P' || s.charAt(i) == 'Q' || s.charAt(i) == 'R' || 
     s.charAt(i) == 'S' || s.charAt(i) == 'T' || s.charAt(i) == 'U' || 
     s.charAt(i) == 'W' || s.charAt(i) == 'X' || s.charAt(i) == 'Y' || 
     s.charAt(i) == 'Z') { 
       sanitize += s.charAt(i); 
     } 
    } 
    if(sanitize.length()>0) { 
     while(sanitize.charAt(0) == '0' || sanitize.charAt(0) == '1' || 
      sanitize.charAt(0) == '2' || sanitize.charAt(0) == '3' || 
      sanitize.charAt(0) == '4' || sanitize.charAt(0) == '5' || 
      sanitize.charAt(0) == '6' || sanitize.charAt(0) == '7' || 
      sanitize.charAt(0) == '8' || sanitize.charAt(0) == '9') { 
       sanitize = sanitize.substring(1, sanitize.length()); 
     } 
    } 
    return sanitize; 
    } 
    return null;  
} 

Répondre

1

je ferais quelque chose comme ceci:

/** 
* 
* HTML 4 Specification ID and NAME tokens must begin with a letter 
* ([A-Za-z]) and may be followed by any number of letters, digits ([0-9]), 
* hyphens ("-"), underscores ("_"), colons (":"), and periods ("."). 
* 
* @param s 
* @return 
*/ 
public static String sanitizeHTMLIdAttribute(String s) { 
    if (s == null) return null; 
    StringBuilder sb = new StringBuilder(); 
    int firstLegal = 0; 
    while (firstLegal < s.length() && !isAZ(s.charAt(firstLegal))) 
     ++firstLegal; 
    for (int i = firstLegal; i < s.length(); ++i){ 
     final char ch = s.charAt(i); 
     if (isOkIdInnerChar(ch)) sb.append(ch); 
    } 
    return sb.length() == s.length()? s : sb.toString(); 
} 

private static boolean isOkIdInnerChar(char ch) { 
    return isAZ(ch) || isNum(ch) || isSpecial(ch); 
} 

private static boolean isSpecial(char ch) { 
    switch (ch) { 
    case '-': case '_': 
    case ':': case '.': 
     return true; 
    default: 
     return false; 
    } 
} 

private static boolean isAZ(char ch) { 
    return ('A' <= ch && ch <= 'Z') || ('a' <= ch && ch <= 'z'); 
} 

private static boolean isNum(char ch) { 
    return '0' <= ch && ch <= '9'; 
} 

... sauf que je préféreriez probablement jeter un NullPointerException si s == null et IllegalArgumentException si s ne contient aucun caractère juridique, mais c'est une question de préférence, bien sûr. Quelques fonctionnalités supplémentaires:

  • Si s est une carte d'identité valide, elle est renvoyée sous-est d'économiser de l'espace (moins de cas de chaîne flottant autour) et le temps (la construction String est cher - oui, je sais l'allocation est pas cher, mais il y a plus de choses que d'allocation).
  • Je ne me Character.isDigit parce qu'il retourne vrai pour tous chiffres Unicode, y compris des choses comme « 3 »
  • Je ne me Character.isLetter parce qu'il retourne vrai pour toutes les lettres Unicode, y compris des choses comme "å"
0

Vous pouvez raccourcir considérablement votre code en utilisant Character.isLetterOrDigit(char); par exemple.

for(int i = 0; i < s.length(); i++) { 
    char c = s.charAt(i); 

    if (Character.isLetterOrDigit(c) || c == '.' || etc ...) { 

    } 
} 

Vous pouvez le faire en conjonction avec le stockage des caractères de ponctuation autorisés dans un Set; par exemple.

private static final Set<Character> ALLOWED = 
    new HashSet<Character>(Arrays.asList('.', '-', '_', ':')); 

for(int i = 0; i < s.length(); i++) { 
    char c = s.charAt(i); 

    if (ALLOWED.contains(c)) { 

    } 
} 
+2

FYI: le caractère e-acute '' \ u00e9'' est une lettre ou un chiffre, mais pas un identifiant HTML valide. Cette méthode retournera vrai pour un large éventail de caractères Unicode. – McDowell

0

Vous pouvez vérifier les expressions (regex est pas mon fort), mais cela ne devrait laisser tomber des caractères non valides:

private static Pattern INVALID_LEADING = Pattern.compile("^[^a-zA-Z]+"); 
    private static Pattern INVALID = Pattern 
     .compile("[^\\w\\u002e\\u003a\\u002d\\u005f]+"); 

    private static String sanitize(String id) { 
    Matcher matcher = INVALID_LEADING.matcher(id); 
    if (matcher.find()) { 
     id = matcher.replaceFirst(""); 
    } 
    Matcher invalid = INVALID.matcher(id); 
    if (invalid.find()) { 
     id = invalid.replaceAll(""); 
    } 
    return id; 
    } 

Si vous n'êtes pas satisfait de regex, sachez que beaucoup de vos personnages sont dans des plages contiguës, peut donc être détecté par les méthodes comme celle-ci:

private static boolean isLatinDigit(char ch) { 
    return ch >= '0' && ch <= '9'; 
    } 
Questions connexes