正则表达式只接受波斯字符

我正在处理一个表单,其中一个自定义validation器应该只接受波斯语字符…我使用了以下代码:

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

但它似乎只适用于检查阿拉伯字符而且它不包括所有波斯字符(它缺少这四个گ,چ,پ,ژ)…有没有办法解决这个问题?

TL; DR

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

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

     ^[\u0622\u0627\u0628\u067E\u062A-\u062C\u0686\u062D-\u0632\u0698\u0633-\u063A\u0641\u0642\u06A9\u06AF\u0644-\u0648\u06CC]+$ 
  • 使用^[۰۱۲۳۴۵۶۷۸۹]+$代表数字或关于你的正则表达式风格:

     ^[\u06F0-\u06F9]+$ 
  • 使用[ ‬ٌ ‬ًّ ‬َ ‬ِ ‬ُ ‬ْ ‬]作为元音或关于你的正则表达式风格:

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

或者这些在一起的组合。 您可能还想在其他字符集中添加其他阿拉伯字母,如Hamza ء

为什么[\u0600-\u06FF][آ-ی]都错了?

虽然\u0600-\u06FF包括:

  • گ与代码点06AF
  • 0686代码点0686
  • 与代码点067E
  • ژ代码点0698

所有提出[\u0600-\u06FF][آ-ی]答案都是错误的。

ie \u0600-\u06FF包含超过你需要的209个字符! 它也包括数字!

在此处输入图像描述

整个故事

这个答案的存在是为了解决一个常见的误解。 代码点060006FF不表示波斯语/波斯语字母表[آ-ی]也不表示):

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

在阿拉伯语块 (0600-06FF)下有255个字符,波斯语字母表有32个字母,除了波斯语数字显示之外,还有42个字母。如果我们添加元音(阿拉伯语元音本来就很少用于波斯语)而没有Tanvin ( ,, ٌ ‬Tashdidّ ‬都是阿拉伯语变音符号的一部分,而不是波斯语,我们最终会得到46个字符。 这意味着\u0600-\u06FF包含超过您需要的209个字符!

۷代码点06F77٧的波斯语表示,代码点06F7是相同数字的阿拉伯语表示。 ۶是波斯语表示的数字6٦是阿拉伯语表示相同的数字。 并且都位于060006FF代码点。

波斯数字四( ۴ ),五( ۵ )和六( ۶ )的形状与阿拉伯语中使用的形状不同,其他数字具有不同的代码点。

您可以看到在波斯语/波斯语中也不存在的其他数量不同的人物,并且在validation名字或姓氏时没有人愿意拥有它们。

[آ-ی]包含117个字符,远远超过某人validation所需的字符。 您可以使用Unicode CLDR查看它们。

您目前在正则表达式中拥有的是标准的阿拉伯符号范围 。 对于其他字符,您需要单独将它们添加到正则表达式。 这是他们的代码:

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

总而言之,你应该拥有

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

除了接受的答案( https://stackoverflow.com/a/22565376/790811 )之外,我们还应该考虑使用Zero-width_non-joiner(或波斯语中的نیمفاصله)字符。 不幸的是我们有2个符号。 一个是标准的,另一个不是标准的,但广泛使用:

  1. \ u200C: http : //en.wikipedia.org/wiki/Zero-width_non-joiner
  2. \ u200F:从右到左的标记( http://unicode-table.com/en/#200F

所以最终的 regix可以是:

 ^[\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编写的,但是你可以使用源代码并复制粘贴字符

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

你可以解决这个问题:persianRex.text.test(yourInput); //返回true或false

这里是完整的文档: http : //imanmh.github.io/persianRex/

波斯语,达里语和塔吉克语都不在我的管辖范围内,但通过Unicode代码图表进行一些翻译告诉我,阿拉伯语涵盖了5个Unicode代码块:

  • 阿拉伯语: http : //www.unicode.org/charts/PDF/U0600.pdf
  • 阿拉伯文补编: http : //www.unicode.org/charts/PDF/U0750.pdf
  • 阿拉伯语扩展-A: http : //www.unicode.org/charts/PDF/U08A0.pdf
  • 阿拉伯语演示表格-A: http : //www.unicode.org/charts/PDF/UFB50.pdf
  • 阿拉伯语演示表格-B: http : //www.unicode.org/charts/PDF/UFE70.pdf

您可以使用命名块而不是显式代码点范围在正则表达式中获取它们(至少其中一些): \p{IsArabicPresentationForms-A}将为您提供前面列表中的第4个Unicode块。

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

我看不懂波斯语,但看看阿拉伯语的unicode补充剂中是否有你想要的字母。

http://www.unicode.org/charts/

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

表示forms(u + FB50-u + FDF​​F)不应在文本中使用,应转换为标准范围(u + 0600-u + 06FF)。

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

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

因此,最终的正则表达式将是:

 ^[\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

我不确定正则表达式是否可以做到这一点,但问题并不仅限于波斯语或阿拉伯语,中文,俄语文本。 所以也许你可以看到你的代码页中是否存在该字符 ,如果不在代码页中,那么我怀疑用户是否可以使用输入设备插入它们….

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

测试测试往返,其中输入应该将字符串与字节匹配并返回。 该链接显示了支持的代码页。