Edit: Я просто понял, что причина результатов я получал то, что ваш пример строки имеет обратную. Комбинированная кодовая точка должна быть второй, а не первой. Я соответствующим образом обновил ответ.
Ну, это зависит от определения «нормализованного».
Например:
/*!
Add this to a `Cargo.toml` manifest:
```cargo
[dependencies]
unicode-normalization = "0.1.1"
```
*/
extern crate unicode_normalization;
fn main() {
for test_str in vec!["a\u{300}", "\u{e0}"] {
is_nfd(test_str);
is_nfkd(test_str);
is_nfc(test_str);
is_nfkc(test_str);
}
}
macro_rules! norm_test {
($fn_name:ident, $norm_name:ident) => {
fn $fn_name(s: &str) {
use unicode_normalization::UnicodeNormalization;
println!("is_{}({:?}):", stringify!($norm_name), s);
let is_norm = s.chars().zip(s.$norm_name())
.inspect(|&(a, b)| println!(" - ({:x}, {:x})", a as u32, b as u32))
.all(|(a, b)| a == b);
println!(" is_norm: {}", is_norm);
}
};
}
norm_test! { is_nfd, nfd }
norm_test! { is_nfkd, nfkd }
norm_test! { is_nfc, nfc }
norm_test! { is_nfkc, nfkc }
Это дает следующий результат:
is_nfd("a\u{300}"):
- (61, 61)
- (300, 300)
is_norm: true
is_nfkd("a\u{300}"):
- (61, 61)
- (300, 300)
is_norm: true
is_nfc("a\u{300}"):
- (61, e0)
is_norm: false
is_nfkc("a\u{300}"):
- (61, e0)
is_norm: false
is_nfd("\u{e0}"):
- (e0, 61)
is_norm: false
is_nfkd("\u{e0}"):
- (e0, 61)
is_norm: false
is_nfc("\u{e0}"):
- (e0, e0)
is_norm: true
is_nfkc("\u{e0}"):
- (e0, e0)
is_norm: true
Так "a\u{300}"
является NFD и NFKD, в то время как это "\u{e0}"
NFC и NFKC. Я не знаю никаких примеров, которые отличаются между вариантами K и non-K, хотя Unicode FAQ on Normalization, вероятно, объяснит все, что я могу.
Так что, если я хочу обнаружить ненормированные диапазоны внутри строки, мне нужно сначала найти диапазоны символов, где только первый имеет «unicode_combining_class», равный нулю, конспектированный). – llogiq
@DK: Вы можете увидеть пример форм K в http://www.unicode.org/reports/tr15/ (например, рисунок 6). По сути, NFD и NFC являются канонической эквивалентностью, а их коллеги K - более слабой эквивалентностью совместимости, которые включают в себя изменение подстрочного сценария/супер-скрипта на обычные персонажи (среди прочего). Например, 2 закодирован как 0032 2075 в NFD или NFC (где 2075 - 5 в позиции супер-сценария), но это 0032 0035 в NFKD или NFKC (где 0035 является обычным 5). –