Как сравнить случай игнорирования символов в примитивных типах
Я пишу эти строки кода:
String name1 = fname.getText().toString();
String name2 = sname.getText().toString();
aru = 0;
count1 = name1.length();
count2 = name2.length();
for (i = 0; i < count1; i++)
{
for (j = 0; j < count2; j++)
{
if (name1.charAt(i)==name2.charAt(j))
aru++;
}
if(aru!=0)
aru++;
}
Я хочу сравнить Character
двух String
, игнорируя случай. Просто использование IgnoreCase
не работает. Добавление значения "65" ASCII
тоже не работает. Как это сделать?
Ответы
Ответ 1
Character
класс Java API имеет различные функции, которые вы можете использовать.
Вы можете преобразовать ваш char в нижний регистр с обеих сторон:
Character.toLowerCase(name1.charAt(i)) == Character.toLowerCase(name2.charAt(j))
Существуют также методы, которые вы можете использовать для проверки, является ли буква прописной или строчной буквой:
Character.isUpperCase('P')
Character.isLowerCase('P')
Ответ 2
Вы не можете выполнить эту задачу с помощью toLowerCase
, либо в строке, либо в символе. Проблема в том, что существуют глифы в верхнем или нижнем регистре, и в зависимости от того, могут ли вы быть или не быть в верхнем регистре, ваши глифы могут быть или не быть сохранены. Это даже не ясно, что вы имеете в виду, когда говорите, что два варианта глифов нижнего регистра сравниваются, игнорируя случай: они или они не совпадают? (Обратите внимание, что есть также глифы смешанного типа: \u01c5, \u01c8, \u01cb, \u01f2
или Dž, Lj, Nj, Dz, но любой предложенный здесь метод будет работать над теми, пока они должны считаться такими же, как и их полностью верхние или полные варианты нижнего регистра.)
Существует дополнительная проблема с использованием Char
: существует не более 80 кодовых точек, не представляемых с помощью одного Char
, которые являются вариантами верхнего/нижнего регистра (по 40), по крайней мере, как определено с помощью кода Java/нижний корпус. Поэтому вам нужно получить коды и изменить их на них.
Но кодовые точки не помогают с глифами вариантов.
В любом случае, здесь полный список глифов, которые являются проблематичными из-за вариантов, показывая, как они сравниваются с 6 вариантами:
- Символ
toLowerCase
- Символ
toUpperCase
- Строка
toLowerCase
- Строка
toUpperCase
- Строка
equalsIgnoreCase
- Символ
toLowerCase(toUpperCase)
(или наоборот)
Для этих методов S
означает, что варианты обрабатываются одинаково друг с другом, D
означает, что варианты рассматриваются как отличные друг от друга.
Behavior Unicode Glyphs
=========== ================================== =========
1 2 3 4 5 6 Upper Lower Var Up Var Lo Vr Lo2 U L u l l2
- - - - - - ------ ------ ------ ------ ------ - - - - -
D D D D S S \u0049 \u0069 \u0130 \u0131 I i İ ı
S D S D S S \u004b \u006b \u212a K k K
D S D S S S \u0053 \u0073 \u017f S s ſ
D S D S S S \u039c \u03bc \u00b5 Μ μ µ
S D S D S S \u00c5 \u00e5 \u212b Å å Å
D S D S S S \u0399 \u03b9 \u0345 \u1fbe Ι ι ͅ ι
D S D S S S \u0392 \u03b2 \u03d0 Β β ϐ
D S D S S S \u0395 \u03b5 \u03f5 Ε ε ϵ
D D D D S S \u0398 \u03b8 \u03f4 \u03d1 Θ θ ϴ ϑ
D S D S S S \u039a \u03ba \u03f0 Κ κ ϰ
D S D S S S \u03a0 \u03c0 \u03d6 Π π ϖ
D S D S S S \u03a1 \u03c1 \u03f1 Ρ ρ ϱ
D S D S S S \u03a3 \u03c3 \u03c2 Σ σ ς
D S D S S S \u03a6 \u03c6 \u03d5 Φ φ ϕ
S D S D S S \u03a9 \u03c9 \u2126 Ω ω Ω
D S D S S S \u1e60 \u1e61 \u1e9b Ṡ ṡ ẛ
Еще более усложняющим является то, что нет никакого способа получить правильное турецкое право (то есть варианты с пунктиром отличаются от тех, которые не указаны), если вы не знаете, что находитесь на турецком языке; ни один из этих методов не дает правильного поведения и не может, если вы не знаете, что языковой стандарт (т.е. нетурецкий: i
и i
- это тот же случай игнорирования, турецкий, а не).
В целом, использование toUpperCase
дает вам самое близкое приближение, поскольку у вас есть только пять вариантов в верхнем регистре (или четыре, не считая турецких).
Вы также можете попытаться конкретно перехватить эти пять неприятных случаев и называть их только toUpperCase(toLowerCase(c))
. Если вы тщательно выберете своих охранников (просто toUpperCase
, если c < 0x130 || c > 0x212B
, а затем выполните другие альтернативы), вы можете получить только ограничение скорости на 20% для символов в низком диапазоне (по сравнению с ~ 4x, если вы конвертируете одиночные символы к строкам и equalsIgnoreCase
их) и только о штрафе 2x, если у вас много в опасной зоне. У вас все еще есть проблема с locale с пунктиром i
, но в остальном вы в приличной форме. Конечно, если вы можете использовать equalsIgnoreCase
для большей строки, вам лучше это сделать.
Вот пример кода Scala, который выполняет задание:
def elevateCase(c: Char): Char = {
if (c < 0x130 || c > 0x212B) Character.toUpperCase(c)
else if (c == 0x130 || c == 0x3F4 || c == 0x2126 || c >= 0x212A)
Character.toUpperCase(Character.toLowerCase(c))
else Character.toUpperCase(c)
}
Ответ 3
Вы можете изменить регистр String перед его использованием, например
String name1 = fname.getText().toString().toLowerCase();
String name2 = sname.getText().toString().toLowerCase();
Затем продолжите операцию отдыха.
Ответ 4
Вы можете поместить оба символа в нижнем регистре, а затем сравнить их.
Ответ 5
Вы должны рассмотреть проблему турецкого языка при сравнении символов/нижнего индекса/верхнего каскада:
Я предлагаю преобразовать в String и использовать toLowerCase с инвариантной культурой (в большинстве случаев, по крайней мере).
public final static Locale InvariantLocale = новый язык (пустой, пустой, пустой);
str.toLowerCase(InvariantLocale)
См. похожие С#
string.ToLower() и string.ToLowerInvariant()
Примечание. Не используйте String.equalsIgnoreCase
http://nikolajlindberg.blogspot.co.il/2008/03/beware-of-java-comparing-turkish.html
Ответ 6
Общие методы сравнения a char в позиции между двумя строками с игнорированием.
public static boolean isEqualIngoreCase(char one, char two){
return Character.toLowerCase(one)==Character .toLowerCase(two);
}
public static boolean isEqualStringCharIgnoreCase(String one, String two, int position){
char oneChar = one.charAt(position);
char twoChar = two.charAt(position);
return isEqualIngoreCase(oneChar, twoChar);
}
Вызов функции
boolean isFirstCharEqual = isEqualStringCharIgnoreCase("abc", "ABC", 0)
Ответ 7
Вот как это делает JDK (адаптировано из OpenJDK 8, String.java/regionMatches):
static boolean charactersEqualIgnoringCase(char c1, char c2) {
if (c1 == c2) return true;
// If characters don't match but case may be ignored,
// try converting both characters to uppercase.
char u1 = Character.toUpperCase(c1);
char u2 = Character.toUpperCase(c2);
if (u1 == u2) return true;
// Unfortunately, conversion to uppercase does not work properly
// for the Georgian alphabet, which has strange rules about case
// conversion. So we need to make one last check before
// exiting.
return Character.toLowerCase(u1) == Character.toLowerCase(u2);
}
Я полагаю, что это работает и для турецких?