正则表达式是否足够,或者我需要检查编码吗?

时间:2014-08-28 12:09:08

标签: java regex character-encoding

我要求确保电子邮件地址包含标准的美国英语字符。如果不讨论这意味着什么以及是否可行,我想知道单独的正则表达式是否足以满足该要求,还是我还需要检查字符集?

在任何情况下,UTF-8字符都可以通过正则表达式,但不能使用正则表达式中使用的拉丁字符集吗?

这是我正在使用的一些代码,在我看来正则表达式已经足够了,但我想要第二个意见。

package misc;

import java.io.UnsupportedEncodingException;

public class ValidateCharacterSet {
    public static void main(String args[]) {
        String czech = "Český";
        String japanese = "日本語";
        String spanish = "¡Qué magnifico es java!";
        String english = "elephant_in-theRoom@yahoo.com";

        System.out.println("iso check: " + czech + ":" + isISO8859(czech));
        System.out.println("iso check: " + japanese + ":" + isISO8859(japanese));
        System.out.println("iso check: " + spanish + ":" + isISO8859(spanish));
        System.out.println("iso check: " + english + ":" + isISO8859(english));

        System.out.println("");

        System.out.println("regex match: " + czech + ":" + playWithMatches(czech));
        System.out.println("regex match: " + japanese + ":" + playWithMatches(japanese));
        System.out.println("regex match: " + spanish + ":" + playWithMatches(spanish));
        System.out.println("regex match: " + english + ":" + playWithMatches(english));
    }


    /**
     * Returns true if the string is null, or the original string (str) equals the string (encodedAsISO8859)
     * that was encoded ISO-8859-1.
     *
     * @param str String containing bytes for which to check the encoding.
     * @return True if the string is in ISO-8859-1 format.
     */
    private static boolean isISO8859(String str) {
        // a null string is compliant by definition.
        if (str == null) {
            return true;
        }

        try {
            byte[] iso88591Data = str.getBytes("ISO-8859-1");
            String encodedAsISO8859 = new String(iso88591Data, "ISO-8859-1");
            if (str.equals(encodedAsISO8859)) {
                return true;
            }
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }

        return false;
    }

    private static boolean playWithMatches(String str) {
        return (str != null && str.matches("[A-Za-z0-9\\-_\\.@\\+]+"));
    }
}

1 个答案:

答案 0 :(得分:1)

我认为你混淆了字符集字符编码。字符集是允许或可用的字符集,而字符编码描述了如何访问字符组。对于像ISO-8859-1这样的字符集,区别并不明显,其中有一个标准编码,即传入一个数字可以获得与该数字相关联的字符。处理像Unicode这样的字符集时更明显,因为一个字符集有多个编码,即UTF-8, UTF-16, UTF-32(Java在其字符串中使用UTF-16)。

一旦定义了字符集的内容,在本例中为“标准美国英语字符”,正则表达式足以检查给定字符串中的字符是否仅包含字符集中的字符。如果没有必要,您不需要,也不想处理较低级别的编码问题。例如,您的isISO8859方法在技术上无法保证正常工作。当给定的字符/字节作为指定字符编码的一部分无效时,您使用的getBytes方法和String构造函数都是documented具有未指定的行为。