我想检测一个字符串是否包含西里尔字母。
在 PHP 中,我做了这样的事情:
preg_match('/\p{Cyrillic}+/ui', $text)
在Java中会有相同的效果吗?
请尝试以下方法:
Pattern.matches(".*\\p{InCyrillic}.*", text)
您也可以避免使用正则表达式,而使用类Character.UnicodeBlock
:
for(int i = 0; i < text.length(); i++) {
if(Character.UnicodeBlock.of(text.charAt(i)).equals(Character.UnicodeBlock.CYRILLIC)) {
// contains Cyrillic
}
}
以下是使用Java 8中的流进行相同操作的另一种方法:
Original Answer翻译成"最初的回答"
text.chars()
.mapToObj(Character.UnicodeBlock::of)
.filter(Character.UnicodeBlock.CYRILLIC::equals)
.findAny()
.ifPresent(character -> ));
或者另一种方式,保留索引:
char[] textChars = text.toCharArray();
IntStream.range(0, textChars.length)
.filter(index -> Character.UnicodeBlock.of(textChars[index])
.equals(Character.UnicodeBlock.CYRILLIC))
.findAny() // can use findFirst()
.ifPresent(index -> );
请注意:我在这里使用字符数组而不是字符串,因为通过索引获取元素具有性能优势。
最初的回答:
请注意:由于通过索引获取元素具有性能优势,因此我在这里使用字符数组而不是字符串。
UnicodeBlock
的示例将正常工作,但如果您喜欢的话,也可以使用 Character.UnicodeScript
enum
:boolean containsCyrillic = "Your String Goes Here".codePoints()
.mapToObj(Character.UnicodeScript::of)
.anyMatch(Character.UnicodeScript.CYRILLIC::equals);
Character.isValidCodePoint
来进行防御。boolean containsCyrillic =
"Your Untrusted String Goes Here".codePoints()
.filter(Character::isValidCodePoint)
.mapToObj(Character.UnicodeScript::of)
.anyMatch(s -> s == Character.UnicodeScript.CYRILLIC);
如果您有兴趣分析文本中的各种脚本,例如确定文本的主要脚本,您可以跟踪各种脚本中的代码点数量:
Map<Character.UnicodeScript,Long> scripts =
"Your Untrusted String Goes Here".codePoints()
.filter(Character::isValidCodePoint)
.mapToObj(Character.UnicodeScript::of)
.collect(groupingBy(
Function.identity(),
counting()));
EnumMap
}},因为Character.UnicodeScript
是一个enum
类型:Map<Character.UnicodeScript,Long> scripts =
"Your Untrusted String Goes Here".codePoints()
.filter(Character::isValidCodePoint)
.mapToObj(Character.UnicodeScript::of)
.collect(groupingBy(
Function.identity(),
() -> new EnumMap<>(Character.UnicodeScript.class),
counting()));
如果你只对多数投票感兴趣,那么你可以尝试这个:
Optional<Character.UnicodeScript> predominantScript =
"Your Untrusted String Goes Here".codePoints()
.filter(Character::isValidCodePoint)
.mapToObj(Character.UnicodeScript::of)
.filter(s -> s != Character.UnicodeScript.COMMON
&& s != Character.UnicodeScript.INHERITED
&& s != Character.UnicodeScript.UNKNOWN)
.collect(groupingBy(
Function.identity(),
() -> new EnumMap<>(Character.UnicodeScript.class),
counting()))
.entrySet()
.stream()
.sorted(
Comparator
.<Map.Entry<Character.UnicodeScript, Long>>comparingLong(Map.Entry::getValue)
.reversed()
.thenComparing(Map.Entry::getKey))
.map(Map.Entry::getKey)
.findFirst();
Character.UnicodeScript.COMMON
、Character.UnicodeScript.INHERITED
和Character.UnicodeScript.UNKNOWN
,因为它们是“通用”类别,用于共享的代码点,映射到所有代码点,或者只是未被识别的代码点(根据规范),而不是个别脚本。