Java에서 HTML ID 속성을 소독하는 기능
-
05-07-2019 - |
문제
다음 기능을 코딩했습니다. 그러나 분명히 누군가는이 작업을 수행하는 더 우아한 방법을 가지고 있습니다.
/**
*
* 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;
}
해결책
나는 다음과 같은 일을 할 것입니다.
/**
*
* 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';
}
... 아마 내가 던지는 것을 선호한다는 점을 제외하고 NullPointerException
만약에 s == null
, 그리고 IllegalArgumentException
만약에 s
법적 문자는 포함되어 있지 않지만 물론 선호도입니다. 몇 가지 추가 기능 :
- 만약에
s
유효한 ID이며 공간을 절약하기 위해 반환됩니다 (주위에 떠 다니는 문자열 인스턴스) 및 시간 (String
건축은 비싸다 - 예, 할당이 저렴하다는 것을 알고 있지만 할당보다 더 많은 일이 있습니다). - 나는 사용하지 않는다
Character.isDigit
그것이 사실이되기 때문에 모두 "٣"와 같은 것들을 포함한 유니 코드 숫자 - 나는 사용하지 않는다
Character.isLetter
그것이 사실이되기 때문에 모두 "Å"과 같은 물건을 포함한 유니 코드 문자
다른 팁
사용하여 코드를 크게 단축 할 수 있습니다 Character.isLetterOrDigit(char)
; 예를 들어
for(int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
if (Character.isLetterOrDigit(c) || c == '.' || etc ...) {
}
}
허용 된 구두점 문자를 Set
; 예를 들어
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)) {
}
}
표현식을 확인하고 싶을 수도 있지만 (Regex는 내 포트가 아님), 이것은 유효하지 않은 문자를 떨어 뜨려야합니다.
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;
}
REGEX에 만족하지 않으면 많은 캐릭터가 인접한 범위에 있으므로 다음과 같은 방법으로 감지 할 수 있습니다.
private static boolean isLatinDigit(char ch) {
return ch >= '0' && ch <= '9';
}
제휴하지 않습니다 StackOverflow