首页 > 解决方案 > 如何使用区域设置对丹麦名称使用正则表达式名称验证?

问题描述

.range 方法中的语言环境是否允许自动检测特殊语言字符?找不到有关此的任何信息,并且在我的实施中不起作用。如果没有,是否有更好的/其他方法来添加对不同语言字符的支持?还是将 UTF 值硬编码为正则表达式的唯一方法?问题是,即使我将丹麦字符硬编码到解决方案中,将来可能需要支持其他语言,那么正确的方法是什么?

import Foundation

func isUserNameValid(userName: String, locale: Locale) -> Bool {
    return userName.range(
        of: #"(?mi)^[a-z](?!(?:.*\.){2})(?!(?:.* ){2})(?!.*\.[a-z])[a-z. ]{1,}[a-z]$"#,
        options: .regularExpression,
        range: nil,
        locale: locale) != nil
}

let inputName = "Lærke"
if isUserNameValid(userName: inputName, locale: Locale(identifier: "da-DK")) {
    print("valid")
} else {
    print("not valid")
}

标签: iosswiftregex

解决方案


.range 方法中的语言环境是否允许自动检测特殊语言字符?

locale 参数用于对区域设置敏感的字符串比较。如果您使用该.regularExpression选项,那么它会完全忽略 locale 参数,因为现在您的正则表达式会准确指定应该如何进行比较,而不需要 locale。

相比:

// nil
"I".range(of: "i", options: .caseInsensitive, range: nil, locale: Locale(identifier: "tr-TR"))

// not nil
"I".range(of: "(?i)i", options: .regularExpression, range: nil, locale: Locale(identifier: "tr-TR"))

在第一种情况下,我使用土耳其语言环境来比较iI,不区分大小写。比较失败是因为在土耳其,小写的 I 看起来像这样:ı(U+0131 LATIN SMALL DOTLESS I)。

在第二种情况下,我做同样的事情,但使用正则表达式。它成功匹配I. 这表明如果您使用正则表达式,它会完全忽略语言环境。

如果我理解您想要正确执行的操作,Locale.exemplarCharacterSet可能对您有用。对于大多数语言,它具有该语言书写系统中的所有字符。您可能需要逐一检查字符串中的每个 unicode 标量,而不是使用正则表达式。

正则表达式可以检查 Unicode 属性\p,但特定语言的字母太具体了。例如,丹麦字母表中的所有字母都具有 script 属性Latin,但许多不在丹麦字母表中的东西也是如此,例如无点 i。


推荐阅读