java - 编码问题; .jar 不适用于 UTF-8 文件中的西里尔字符

标签 java encoding

所以我在代码中将此正则表达式作为字符串文字:

private static final String FILE_PATTERN = "((\\s*\".*НЕКОТОРЫЕ СИМВОЛЫ .*\"\\R)([^\"].* (?!-)\\d+\\s*)+)+";

我还有 UTF-8 编码的输入测试文件。

问题是,当我在 IDE(本例中为 IntelliJ IDEA)中测试我的程序时,一切正常。特别是,正则表达式可以处理测试文件中的西里尔字符。

但是当我构建我的程序(Maven)并使用相同的测试文件测试 .jar 文件时,结果发现正则表达式很可能无法使用西里尔字符。

然后我用 Windows 1251 编码的文件再次测试它,它成功了。

所以我的问题是 - 如何让我的 .jar 使用 UTF-8 文件,就像在 IDE 中一样?

提前致谢。

<小时/>

[更新1]

two test files, one in UTF-8 and another in Windows 1251

我尝试用\u 代码替换西里尔字符,如下所示:

private static final String FILE_PATTERN = "((\\s*\".*\\u041E\\u0442\\u0434\\u0435\\u043B .*\"\\R)([^\"].* (?!-)\\d+\\s*)+)+";

这不起作用:(

<小时/>

[更新2]

文件处理开始如下:

static void processFile(String inputFile) {
    try {
        String fileStr = FileHandler.readFile(inputFile).toString();
        if (!FileParser.validateFile(fileStr)) {
            System.out.println("Sorry, input file format is invalid");
            ...

文件验证如下所示:

public class FileParser {
private static final String FILE_PATTERN = "((\\s*\".*Отдел .*\"\\R)([^\"].* (?!-)\\d+\\s*)+)+";

public static boolean validateFile(String fileStr) {
    return Pattern.compile(FILE_PATTERN).matcher(fileStr).matches();
}
...

我认为文件读取很常见:

public class FileHandler {
public static StringBuilder readFile(String fileName) {
    StringBuilder res = new StringBuilder();
    String temp;
    try (BufferedReader r = new BufferedReader(new FileReader((fileName)))) {
        while ((temp = r.readLine()) != null) {
            res.append(temp).append("\n");
        }
    } catch (FileNotFoundException e) { 
        System.out.println("Input file not found!");
    } catch (IOException e) {
        // log exception
    }
    return res;
}
...

最佳答案

我会针对这个问题提出一些可能性。

类 FileReader 和 FileWriter 使用默认平台编码,没有指定编码的重载。我不确定这是否是有意为之,但替代方案之一:

public static StringBuilder readFile(String fileName) {
    StringBuilder res = new StringBuilder();
    String temp;
    Charset charset = StandardCharsets.UTF_8;
    //Charset charset = Charset.fromName("Windows-1251");
    try (BufferedReader r = Files.newBufferedReader(fileName, charset)) {
        while ((temp = r.readLine()) != null) {
            res.append(temp).append("\n");
        }
    } catch (FileNotFoundException e) { 
        System.out.println("Input file not found!");
    } catch (IOException e) {
        // log exception
    }
    return res;
}

或者:

String readFile(String fileName) throws IOException {
    byte[] content = Files.readAllBytes(Paths.get(fileName));
    return new String(content, StandardCharsets.UTF_8);
}

那么java源代码的编辑器编码必须与javac编译器编码相同。人们可以通过使用此类特殊字符的 \uXXXX ASCII 表示来检查这一点:如果它突然起作用,...

你使用了两个反斜杠,但是\u0063(字母c)可以在java源代码级别工作,事实上你可以代替public classpubli\u0063\u0063lass

private static final String FILE_PATTERN =
    "((\\s*\".*\u041E\u0442\u0434\u0435\u043B .*\"\\R)([^\"].* (?!-)\\d+\\s*)+)+";

然后是正则表达式,它有两个 Unicode 标志,(?u)(?U),下面更多地表示字母 构成。这在这里应该不是问题。

关于java - 编码问题; .jar 不适用于 UTF-8 文件中的西里尔字符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47802828/

相关文章:

java - 如何修改二叉搜索树的遍历?

java - 使用 Gradle 版本 2.2.3 在 android studio 项目中无法识别方法 testCompile?

java - 了解字符流中的编码

javascript - 如何通过 URL 传递撇号?

algorithm - 将 URL 编码(和解码)为一串字母

java - 两种代码哪一种更正确?

java - CentOs 7 - Java SQL 错误

java - token 空指针异常

c - 使用 C 中的极坐标方法向帧添加噪声

java - 为什么在 java 6 和 java 7 中获取字符 ®(U+00AE) 不同?