public static void main(String[] args) throws IOException {
String str1 ="ΔΞ123456";
System.out.println(str1+"-"+str1.matches("^\\p{InGreek}{2}\\d{6}")); //ΔΞ123456-true
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String str2 = br.readLine(); //ΔΞ123456 same as str1.
System.out.println(str2+"-"+str2.matches("^\\p{InGreek}{2}\\d{6}")); //Ξ"Ξ?123456-false
System.out.println(str1.equals(str2)); //false
}
从键盘读取时,相同的String与regex不匹配。
是什么导致了这个问题,我们如何解决呢?
提前致谢。
编辑:我使用System.console()进行输入和输出。
public static void main(String[] args) throws IOException {
PrintWriter pr = System.console().writer();
String str1 ="ΔΞ123456";
pr.println(str1+"-"+str1.matches("^\\p{InGreek}{2}\\d{6}")+"-"+str1.length());
String str2 = System.console().readLine();
pr.println(str2+"-"+str2.matches("^\\p{InGreek}{2}\\d{6}")+"-"+str2.length());
pr.println("str1.equals(str2)="+str1.equals(str2));
}
输出:
ΔΞ123456-true-8
ΔΞ123456
ΔΞ123456-true-8
str1.equals(str2)=true
您如何知道str2与str1相同?您使用什么方法来验证它们实际上是相同的?
你是对的马克。它和我想的不一样。
打印出所有Java属性:System.getProperties()。list(System.out);查找" file.encoding"。
file.encoding = UTF-8
请注意,希腊语块中有一些代码点不在希腊语脚本中,并且类似地,有许多代码点在希腊语脚本中但不在希腊语块中。以unichars -u \p{InGreek} \P{IsGreek} | wc -l运行的unichars程序显示第一组中有28个,而unichars -a \p{IsGreek} \P{InGreek} | wc -l显示第二组中有395。另请参阅uniprops程序,以另一种方式探索事物。
我可能应该补充一点,Java直到JDK7才支持Unicode脚本类型!您可以使用[\p{InGreek}\p{InGreekExtended}\p{InAncientGreekNumbers}\p{InAncientGreekMusicalNotation}],但是在这四个非Script=Greek类型的块中仍然有66个代码点。
您正在使用哪个IDE? JDK版本+1!
您是否同时使用javac ?encoding UTF?8进行编译并同时使用java ?Dfile.encoding=UTF?8运行?
@Stefanos:@Whom,您正在解决IDE问题吗?
@tchrist:我对那些术语(脚本,块)不熟悉,但是指出这一点很好。我试过javac?encoding UTF?8和java?Dfile.encoding = UTF?8没有用。
@Stefanos:如果您要问我,我正在使用最新的Eclipse(3.6.1)。和jdk1.6.0_23
这里有多个地方可能发生转码错误。
确保正确编译了您的类(在IDE中不太可能出现问题):
确保编译器使用与编辑器相同的编码(即,如果另存为UTF-8,则将编译器设置为使用该编码)
或者切换到转义为大多数编码是ASCII码集的ASCII子集(即,将字符串文字更改为"\u0394\u039e123456")
确保您使用正确的编码读取输入:
使用控制台读取输入-此类将检测控制台编码
或将您的Reader配置为使用正确的编码(可能是Windows-1253)或将控制台设置为Java的默认编码
请注意,System.console()在IDE中返回null,但是您可以对此做一些事情。
如果使用Windows,则可能是由于控制台字符编码(" OEM代码页")与系统编码(" ANSI代码页")不同所致。
没有显式编码参数的InputStreamReader假定输入数据采用系统默认编码,因此从控制台读取的字符被错误地解码。
为了在Windows控制台中正确读取非us-ascii字符,您需要在构造InputStreamReader时显式指定控制台编码(可以通过在命令行中执行mode con cp找到所需的代码页号):
相同的问题适用于输出,您需要使用正确的编码构造PrintWriter:
PrintWriter out = new PrintWrtier(new OutputStreamWriter(System.out,"CP737"));
请注意,从Java 1.6开始,您可以使用从System.console()获得的Console对象来避免这些变通办法。它为Reader和Writer提供正确配置的编码以及一些实用程序方法。
但是,重定向流(例如,从IDE运行时)时,System.console()返回null。可在McDowell的答案中找到解决此问题的方法。
也可以看看:
代码页
我尝试了BufferedReader br = new BufferedReader(new InputStreamReader(System.in," UTF-8"));但没有工作。我也尝试过CP1253。
@athspk:您需要希腊语Windows的OEM代码页。它应该是CP737或CP869,我不确定是哪一个。
他们也不工作。
@athspk:str2.length()的结果是什么?
3456"Ξ?123456-false-10
@athspk:输出清楚地表明您已将UTF-8输入解释为Windows-1252。您确定new InputStreamReader(System.in,"UTF-8"))无效吗?
无论是从IDE还是从命令行运行,它都不起作用。当我从命令行运行时,str2为123456,长度现在为8(与str1相同)
@athspk:您可以尝试按照McDowell的建议通过System.console()读取输入。另外,mode con cp命令显示什么?
模式con cp =737。在从IDE运行时,我之前尝试过新的InputStreamReader(System.in," 737"),但没有工作。现在我从命令行运行它,并且正则表达式匹配!输出:─╬123456-true如何获得正确打印的字符串?
@athspk:对于输出,您需要使用正确的编码创建PrintWriter,与输入相同。从Java 1.6开始,您还可以通过使用System.console()作为输入和输出来避免所有这些问题。
两种情况下我都正确,您的代码没有任何变化。 (我使用希腊布局键盘进行了测试-我来自希腊:])
可能是您的键盘正在以8859-7 ISO(而不是UTF-8)发送ascii。我的发送UTF-8。
编辑:我仍然通过添加equals命令来实现..
System.out.println(str1.equals(str2));
通过将区域选项中的所有内容更改为希腊语(如果使用的是Windows),检查是否可以使其正常运行。
Rundll32 Shell32.dll,Control_RunDLL Intl.cpl,,0
如果是这种情况,那么您可以采取相应行动..如" axtavt"所说
一切都已经用希腊语了。谢谢Stefane :-)
键盘可能不会将字符作为UTF-8发送,而是作为操作系统的默认字符编码发送。
也可以看看
Java:如何确定流的正确字符集编码
Java App:无法正确读取iso-8859-1编码的文件