所以我在代码中将此正则表达式作为字符串文字:
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 class
写publi\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/