我需要创建一个与https://www.w3.org/2005/xpath-functions/collation/html-ascii-case-insensitive/对应的Collator,即在进行比较时忽略ASCII A-Z
和a-z
字符的区分大小写。
我尝试使用以下ICU4j RuleBasedCollator
:
final RuleBasedCollator collator =
new RuleBasedCollator("&a=A, b=B, c=C, d=D, e=E, f=F, g=G, h=H, "
+ "i=I, j=J, k=K, l=L, m=M, n=N, o=O, p=P, q=Q, r=R, s=S, t=T, "
+ "u=U, v=V, u=U, v=V, w=W, x=X, y=Y, z=Z").freeze();
然而,以下比较似乎失败了,我希望它能成功(即返回true
):
final SearchIterator searchIterator = new StringSearch(
"pu", new StringCharacterIterator("iNPut"), collator);
return searchIterator.first() >= 0;
我的规则中缺少什么?
答案 0 :(得分:3)
这个W3C“整理”看起来并不像通常意义上的Collator。它是一个没有排序的ASCII不区分大小写的匹配器。我怀疑它通常是用低级代码实现的,它不区分大小写地匹配ASCII字母而其他所有字符都是精确匹配的。请参阅https://www.w3.org/TR/xpath-functions-31/#html-ascii-case-insensitive-collation
Collator规则可能不会按照您的想法执行。逗号是三级差异的旧语法,因此&a=A, b=B, c=C
与&a=A<<<b=B<<<c=C
相同。我认为你打算像&a=A &b=B &c=C
等等。
答案 1 :(得分:2)
com.ibm.icu.text.RuleBasedCollator#compare
返回一个整数值。如果source小于target,则值小于零,如果source和target相等则值为零,如果source大于target,则值大于零
String a = "Pu";
String b = "pu";
RuleBasedCollator c1 = (RuleBasedCollator) Collator.getInstance(new Locale("en", "US", ""));
RuleBasedCollator c2 = new RuleBasedCollator("& p=P");
System.out.println(c1.compare(a, b) == 0);
System.out.println(c2.compare(a, b) == 0);
Output
======
false
true
似乎规则不在于问题所在,SearchIterator代码似乎有问题。
如果您不必使用SearchIterator,那么也许您可以编写自己的“包含”方法。也许是这样的:
boolean contains(String a, String b, RuleBasedCollator c) {
int index = 0;
while (index < a.length()) {
if (a.length() < b.length()) {
return false;
}
if (c.compare(a.substring(0, b.length()), b) == 0) {
return true;
}
a = a.substring(1);
}
return false;
}
也许不是世界上最好的代码,但你明白了。