只接受波斯字符的 regex

我正在做一个表单,其中一个自定义验证器应该只接受波斯字符。我使用了以下代码:

var myregex = new Regex(@"^[\u0600-\u06FF]+$");
if (myregex.IsMatch(mytextBox.Text))
{
args.IsValid = true;
}
else
{
args.IsValid = false;
}

然而,它似乎只能检测到阿拉伯文字符,因为它没有覆盖所有的波斯文字符(它缺少这四个: ,,)。

有办法解决这个问题吗?

19365 次浏览

当前正则表达式中包含的是 标准阿拉伯符号范围。对于其他字符,您需要将它们分别添加到正则表达式中。这是他们的密码:

ژ \u0698
پ \u067E
چ \u0686
گ \u06AF

所以总而言之,你应该

^[\u0600-\u06FF\u0698\u067E\u0686\u06AF]+$

波斯语、达日语和塔吉克语不在我的管辖范围之内,但是通过对 Unicode 代码图表的小小翻阅,我发现阿拉伯语包含5个 Unicode 代码块:

您可以使用 叫做积木而不是显式的代码点范围在正则表达式中获得它们(至少其中的一些) : \p{IsArabicPresentationForms-A}将给出前面列表中的第4个 Unicode 块。

您也可以阅读 Unicode: http://behdad.org/download/Publications/persiancomputing/a007.pdf中的波斯计算

除了可接受的答案(https://stackoverflow.com/a/22565376/790811)之外,我们还应该考虑 Zero-width _ non-join er (或波斯语)字符。 不幸的是,我们有两个符号,一个是标准的,另一个不是标准的,但广泛使用:

  1. U200C: http://en.wikipedia.org/wiki/Zero-width_non-joiner
  2. U200F: 右至左符号(http://unicode-table.com/en/#200F)

因此,期末考试正则表达式可以是:

^[\u0600-\u06FF\uFB8A\u067E\u0686\u06AF\u200C\u200F]+$

如果你想考虑“ 空间”,你可以这样做:

^[\u0600-\u06FF\uFB8A\u067E\u0686\u06AF\u200C\u200F ]+$

你可以通过以下方法测试 JavaScript:

/^[\u0600-\u06FF\uFB8A\u067E\u0686\u06AF7\u200C\u200F ]+$/.test('ای‌پسر تو چه می‌دانی؟')

注意: persianRex 是用 Javascript 编写的,不过你可以使用源代码复制粘贴字符

由于键盘布局和操作系统的真实性,检测波斯字符是一项棘手的任务。之前我也遇到过同样的挑战,所以我决定编写一个开源库来解决这个问题。

你可以这样解决你的问题: Test (yourInput) ;//返回 true 或 false

以下是完整的文档: Http://imanmh.github.io/persianrex/

命名块,例如 p {阿拉伯}覆盖整个 阿拉伯文,而不仅仅是波斯字符。

表示形式(u + FB50-u + FDFF)应以文本形式使用 没有,并应转换为标准范围(u + 0600-u + 06FF)。

为了只覆盖波斯语,我们需要以下内容:

  • 标准阿拉伯语范围外的波斯语字符子集,即(U + 0621-U + 0624,U + 0626-U + 063 A,U + 0641-U + 0642,U + 0644-U + 0648)
  • 标准阿拉伯语发音符号(U + 064 B-U + 0652)
  • 另外两个变音符(U + 0654,U + 0670)
  • 4个额外的波斯语字符“”(U + 067 E,U + 0686,U + 0698,U + 06 AF)
  • U + 06 A9: 波斯卡夫(正式名称: “阿拉伯字母 Keheh”; 与阿拉伯卡夫不同的符号)
  • U + 06CC: 波斯语 Yeh (与阿拉伯语 Yeh 不同的表示法)
  • U + 200C: 零宽度非连接器

因此,得到的 regexp 将是:

^[\u0621-\u0624\u0626-\u063A\u0641-\u0642\u0644-\u0648\u064B-\u0652\u067E\u0686\u0698\u06AF\u06CC\u06A9\u0654\u670\u200c}]+$

另请参阅这里列出的波斯文字样本:

Http://unicode.org/cldr/trac/browser/trunk/common/main/fa.xml

DR

波斯语必须使用的字符集如下:

  • 使用 ^[آابپتثجچحخدذرزژسشصضطظعغفقکگلمنوهی]+$表示字母或使用与正则表达式风格相关的代码点(并非所有引擎都支持 \uXXXX表示法) :

    ^[\u0622\u0627\u0628\u067E\u062A-\u062C\u0686\u062D-\u0632\u0698\u0633-\u063A\u0641\u0642\u06A9\u06AF\u0644-\u0648\u06CC]+$
    
  • Use ^[۰۱۲۳۴۵۶۷۸۹]+$ for numbers or regarding your regex flavor:

    ^[\u06F0-\u06F9]+$
    
  • Use [ ‬ٌ ‬ًّ ‬َ ‬ِ ‬ُ ‬ْ ‬] for vowels or regarding your regex flavor:

    [\u202C\u064B\u064C\u064E-\u0652]
    

or a combination of those together. You may want to add other Arabic letters like Hamza ء to your character set additionally.

Why are [\u0600-\u06FF] and [آ-ی] both wrong?

Although \u0600-\u06FF includes:

  • گ with codepoint 06AF
  • چ with codepoint 0686
  • پ with codepoint 067E
  • ژ with codepoint 0698

as well, all answers that suggest [\u0600-\u06FF] or [آ-ی] are simply WRONG.

i.e. \u0600-\u06FF contains 209 more characters than you need! and it includes numbers too!

enter image description here

Whole story

This answer exists to fix a common misconception. Codepoints 0600 through 06FF do not denote Persian / Farsi alphabet (neither does [آ-ی]):

[\u0600-\u0605 ؐ-ؚ\u061Cـ ۖ-\u06DD ۟-ۤ ۧ ۨ ۪-ۭ ً-ٕ ٟ ٖ-ٞ ٰ ، ؍ ٫ ٬ ؛ ؞ ؟ ۔ ٭ ٪ ؉ ؊ ؈ ؎ ؏
۞ ۩ ؆ ؇ ؋ ٠۰ ١۱ ٢۲ ٣۳ ٤۴ ٥۵ ٦۶ ٧۷ ٨۸ ٩۹ ءٴ۽ آ أ ٲ ٱ ؤ إ ٳ ئ ا ٵ ٮ ب ٻ پ ڀ
ة-ث ٹ ٺ ټ ٽ ٿ ج ڃ ڄ چ ڿ ڇ ح خ ځ ڂ څ د ذ ڈ-ڐ ۮ ر ز ڑ-ڙ ۯ س ش ښ-ڜ ۺ ص ض ڝ ڞ
ۻ ط ظ ڟ ع غ ڠ ۼ ف ڡ-ڦ ٯ ق ڧ ڨ ك ک-ڴ ػ ؼ ل ڵ-ڸ م۾ ن ں-ڽ ڹ ه ھ ہ-ۃ ۿ ەۀ وۥ ٶ
ۄ-ۇ ٷ ۈ-ۋ ۏ ى يۦ ٸ ی-ێ ې ۑ ؽ-ؿ ؠ ے ۓ \u061D]

255个字符属于 阿拉伯文(0600-06FF) ,波斯语字母表有32个字母,除了波斯语的数字演示,它将是42。如果我们在没有 坦文(ًٍِ ‬ٌ ‬)和 Tashdid(ّ ‬)的情况下添加元音(最初是阿拉伯语元音,很少在波斯语中使用) ,这两个元音都是阿拉伯语发音符号的子集,而不是波斯语,我们最终会得到46个字符。这意味着 \u0600-\u06FF包含的字符比你需要的多209个!

具有代码点 06F7۷是数字 7的波斯语表示,具有代码点 0667٧是相同数字的阿拉伯语表示。۶是数字 6的波斯语表示,٦是相同数字的阿拉伯语表示。并且所有都驻留在 0600通过 06FF代码点。

波斯数字4(۴)、5(۵)和6(۶)的形状如下 不同于阿拉伯语和其他数字所使用的形状 不同的密码。

你可以看到不同数量的其他字符,不存在于波斯语/波斯语太和没有人愿意有他们同时验证一个名字或姓氏。

[آ-ی]也包含了117个字符,这比验证需要的字符要多得多。您可以使用 一个 href = “ https://Unicode.org/CLDR/tility/list-unicodeset.jsp”rel = “ noReferrer”> Unicode CLDR 看到它们。

我不确定 regex 是否是解决这个问题的方法,但是这个问题并不仅仅针对波斯语或阿拉伯语、中文和俄语文本。所以也许你可以看到如果 字符存在于代码页中,如果不在代码页,那么我怀疑用户可以插入他们使用输入设备... 。

 var encoding = Encoding.GetEncoding(1256);
var expect = "گ چ پ ژ";
var actual= encoding.GetBytes("گ چ پ ژ");
Assert.AreEqual(encoding.GetString(actual),expect);

该测试测试一个往返过程,其中输入应该将字符串匹配到字节并返回。该链接显示支持的那些代码页。

我搜索了很多波斯语电话号码的验证方法,比如在 laravel 中使用 regex,但是没有找到合适的答案。所以我决定把 peisan 号码改成英文,然后自己验证。这对我很有帮助,希望这能有所帮助:

if (is_numeric($mobile) && strlen($mobile) == 11) {
// if number in english
}else{
$mobile = str_split($mobile , 2);
if (count($mobile) != 11) {
return redirect()->back()->withErrors('فرمت شماره موبایل باید عدد و ۱۱ رقم باشد');
}
foreach ($mobile as $key => $number) {
if ($number == '۰') {
$mobile[$key] = 0;
}elseif ($number == '۱') {
$mobile[$key] = 1;
}elseif ($number == '۲') {
$mobile[$key] = 2;
}elseif ($number == '۳') {
$mobile[$key] = 3;
}elseif ($number == '۴') {
$mobile[$key] = 4;
}elseif ($number == '۵') {
$mobile[$key] = 5;
}elseif ($number == '۶') {
$mobile[$key] = 6;
}elseif ($number == '۷') {
$mobile[$key] = 7;
}elseif ($number == '۸') {
$mobile[$key] = 8;
}elseif ($number == '۹') {
$mobile[$key] = 9;
}
}
$mobile = implode($mobile);
if(is_numeric($mobile) == false){
return redirect()->back()->withErrors('فرمت شماره موبایل باید عدد و ۱۱ رقم باشد');
}
}

只需将此代码添加到您的 TextFieldTextFormField

例如:

inputFormatters: [FilteringTextInputFormatter.allow(RegExp("[ آ-ی]"))],

要创建一个空白空间,只需在 RegEx列表中输入一个空格

♥♥♥♥♥♥