Включает ли поддержка юникода регулярных выражений Java полное сворачивание регистра?
Предполагая эти определения строк:
String lowerStream = "flüßchen";
String upperStream = "FLÜSSCHEN";
String streamPattern = ".*(ss).*";
Используя этот шаблон:
Pattern pattern = Pattern.compile(streamPattern, Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE);
... это утверждение проходит:
assertThat( pattern.matcher(upperStream).find() ).isTrue()
... а вот этот не работает:
assertThat( pattern.matcher(lowerStream).find() ).isTrue()
... тогда как оба
lowerStream
а также
upperStream
перейдите на rubular.com с каждым из этих регулярных выражений:
/.*(ss).*/i
/.*(SS).*/i
/.*(ß).*/i
Также невозможно получить успешное сравнение, используя любой из
String.equalsIgnoreCase()
,
String.toLowerCase().equals()
, или
String.toUpperCase().equals()
.
Поддерживает ли регулярное выражение java unicode только простое складывание регистра? Если да, то почему это явно не задокументировано?
1 ответ
В моей системе кажется, что нижний регистр правильно преобразуется в верхний:
public class IfTesting {
public static void main( String[] args ) {
String lowerStream = "flüßchen";
String upperStream = "FLÜSSCHEN";
System.out.println( "upper case: " + Arrays.toString( upperStream.getBytes()) );
System.out.println( "lower case to upper: " + Arrays.toString( lowerStream.toUpperCase().getBytes() ) );
}
}
Результаты на выходе:
run:
upper case: [70, 76, -61, -100, 83, 83, 67, 72, 69, 78]
lower case to upper: [70, 76, 85, -52, -120, 83, 83, 67, 72, 69, 78]
BUILD SUCCESSFUL (total time: 0 seconds)
И вы можете видеть, что на выходе появляется «S» (десятичное число 83). Я не знаю, поможет ли это, но на каком-то уровне кажется, что Java понимает, как преобразовывать предоставленные вами символы. OTOH Я предполагаю, что, поскольку 83 явно находится в диапазоне ASCII, он будет преобразован в нижний регистр ASCII 's', если вы попытаетесь пойти другим путем. Так что может быть лучше преобразовать в верхний регистр. Вы используете строчную букву «ss» в строке соответствия.