拉丁字符检查

Latin Characters check

本文关键字:检查 字符 丁字符      更新时间:2023-09-26

有一些类似的问题,但没有一个是完全相同的,或者有一个适合我的答案。

我需要一个javascript函数来验证文本字段是否包含所有有效的拉丁字符,所以没有丙烯酸或中文,只是拉丁语;具体来说:

Basic Latin(不包括C0控制字符),Latin-1(不包括(C1控制字符),拉丁扩展A,拉丁扩展B和拉丁语扩展附加的这个集合对应于Unicode码点U+0020 ~ U+007E、U+00A0 ~ U+024F、U+IE00 ~ U+IEFF

有些答案似乎检查了文本字段中的第一个字符,但遗漏了其他字符,所以这些都不好。

这是我到目前为止尝试过的(这不起作用!):

var value = 'abcdef' // from text field
var re = ''u0000-'u007F|'u0100-'u017F|'u0180-'u024F|'u1E00-'u1EFF|'u0080-'u00FF'; // latin regexp string
// var re = '''w+/'; // alternative
if (new RegExp(re).test(value)) {
    result = false;
}

下面的分类只适用于第一个字符:

//var re = ''u0000-'u007F|'u0100-'u017F|'u0180-'u024F|'u1E00-'u1EFF|'u0080-'u00FF'; // latin regexp string
// couldn't get the above to work so using the following:
var re = '''w+';
if (!value.match(re)) {
    message = 'Please enter valid latin characters only';
    $focusField = $this;
}

正确的方法是什么?

我确实需要代码,而不是解释,但两者都更好。

谢谢

EDIT:注意,接受的答案中给出的解是不正确的。它充满了假阳性和假阴性。本文底部给出了所需的确切数字代码点。

问题给出的例子错误地试图使用块而不是脚本属性!

你不希望在这里使用Unicode块字符属性;您希望使用Unicode脚本字符属性。换句话说,您确实希望Script=Latin而不是尝试使用Block=Basic_Latin + Block=Latin_1 + Block=Latin_1_Supplement + Block=Latin_Extended_A + Block=Latin_Extended_Additional

还要注意,这个问题忽略了其他拉丁块:Block=Latin_Extended_CBlock=Latin_Extended_D .

即使您使用正确的块,您也会得到145个假阳性,这些块中不是拉丁字母字符:

$ unichars ''P{Script=Latin}' '['p{Block=Basic_Latin}'p{Block=Latin_1}'p{Block=Latin_1_Supplement}'p{Block=Latin_Extended_A}'p{Block=Latin_Extended_B}
'p{Block=Latin_Extended_Additional}'p{Block=Latin_Extended_C}'p{Block=Latin_Extended_D}]' | wc -l
145

此外,您将错过403个假阴性,这些假阴性确实是拉丁字母字符,但不在这些块中:

$ unichars ''p{Script=Latin}' '[^'p{Block=Basic_Latin}'p{Block=Latin_1}'p{Block=Latin_1_Supplement}'p{Block=Latin_Extended_A}'p{Block=Latin_Extended_B
}'p{Block=Latin_Extended_Additional}'p{Block=Latin_Extended_C}'p{Block=Latin_Extended_D}]' | wc -l
403

实际上从不想要使用块;您想要使用脚本。这就是为什么uts# 18的一级一致性要求在需求1.2中支持Script字符属性,但直到需求2.7:完整属性才提到Block属性。

请参阅UTS#18附录A,字符块,以了解使用块而不是脚本的更多陷阱。

删除位于基本多语言平面之外的代码点,因为Javascript错误使得无法按范围指定这些代码点,我们留下了这组不可维护的乱码需要找出所有具有拉丁,通用或继承脚本字符属性的Unicode v6.2代码点:

['u0000-'u0040]['u0041-'u005A]['u005B-'u0060]['u0061-'u007A]['u007B-'u00A9]'u00AA['u00AB-'u00B9]'u00BA['u00BB-'u00BF]['u00C0-'u00D6]'u00D7['u00D8-'u00
F6]'u00F7['u00F8-'u02B8]['u02B9-'u02DF]['u02E0-'u02E4]['u02E5-'u02E9]['u02EC-'u02FF]['u0300-'u036F]'u0374'u037E'u0385'u0387['u0485-'u0486]'u0589'u060C
'u061B'u061F'u0640['u064B-'u0655]['u0660-'u0669]'u0670'u06DD['u0951-'u0952]['u0964-'u0965]'u0E3F['u0FD5-'u0FD8]'u10FB['u16EB-'u16ED]['u1735-'u1736]['u
1802-'u1803]'u1805['u1CD0-'u1CD2]'u1CD3['u1CD4-'u1CE0]'u1CE1['u1CE2-'u1CE8]['u1CE9-'u1CEC]'u1CED['u1CEE-'u1CF3]'u1CF4['u1CF5-'u1CF6]['u1D00-'u1D25]['u
1D2C-'u1D5C]['u1D62-'u1D65]['u1D6B-'u1D77]['u1D79-'u1DBE]['u1DC0-'u1DE6]['u1DFC-'u1DFF]['u1E00-'u1EFF]['u2000-'u200B]['u200C-'u200D]['u200E-'u2064]['u
206A-'u2070]'u2071['u2074-'u207E]'u207F['u2080-'u208E]['u2090-'u209C]['u20A0-'u20BA]['u20D0-'u20F0]['u2100-'u2125]['u2127-'u2129]['u212A-'u212B]['u212
C-'u2131]'u2132['u2133-'u214D]'u214E['u214F-'u215F]['u2160-'u2188]'u2189['u2190-'u23F3]['u2400-'u2426]['u2440-'u244A]['u2460-'u26FF]['u2701-'u27FF]['u
2900-'u2B4C]['u2B50-'u2B59]['u2C60-'u2C7F]['u2E00-'u2E3B]['u2FF0-'u2FFB]['u3000-'u3004]'u3006['u3008-'u3020]['u302A-'u302D]['u3030-'u3037]['u303C-'u30
3F]['u3099-'u309A]['u309B-'u309C]'u30A0['u30FB-'u30FC]['u3190-'u319F]['u31C0-'u31E3]['u3220-'u325F]['u327F-'u32CF]['u3358-'u33FF]['u4DC0-'u4DFF]['uA70
0-'uA721]['uA722-'uA787]['uA788-'uA78A]['uA78B-'uA78E]['uA790-'uA793]['uA7A0-'uA7AA]['uA7F8-'uA7FF]['uA830-'uA839]['uFB00-'uFB06]['uFD3E-'uFD3F]'uFDFD
['uFE00-'uFE0F]['uFE10-'uFE19]['uFE20-'uFE26]['uFE30-'uFE52]['uFE54-'uFE66]['uFE68-'uFE6B]'uFEFF['uFF01-'uFF20]['uFF21-'uFF3A]['uFF3B-'uFF40]['uFF41-'
uFF5A]['uFF5B-'uFF65]'uFF70['uFF9E-'uFF9F]['uFFE0-'uFFE6]['uFFE8-'uFFEE]['uFFF9-'uFFFD]
就我个人而言,我会解雇任何试图使用这种废话的人。

此外,由于Javascript在处理完整Unicode时的错误而错过的3225个代码点如下:

10100-10102 10107-10133 10137-1013F 10190-1019B 101D0-101FC 101FD
1D000-1D0F5 1D100-1D126 1D129-1D166 1D167-1D169 1D16A-1D17A 1D17B-1D182
1D183-1D184 1D185-1D18B 1D18C-1D1A9 1D1AA-1D1AD 1D1AE-1D1DD 1D300-1D356
1D360-1D371 1D400-1D454 1D456-1D49C 1D49E-1D49F 1D4A2 1D4A5-1D4A6
1D4A9-1D4AC 1D4AE-1D4B9 1D4BB 1D4BD-1D4C3 1D4C5-1D505 1D507-1D50A
1D50D-1D514 1D516-1D51C 1D51E-1D539 1D53B-1D53E 1D540-1D544 1D546
1D54A-1D550 1D552-1D6A5 1D6A8-1D7CB 1D7CE-1D7FF 1F000-1F02B 1F030-1F093
1F0A0-1F0AE 1F0B1-1F0BE 1F0C1-1F0CF 1F0D1-1F0DF 1F100-1F10A 1F110-1F12E
1F130-1F16B 1F170-1F19A 1F1E6-1F1FF 1F201-1F202 1F210-1F23A 1F240-1F248
1F250-1F251 1F300-1F320 1F330-1F335 1F337-1F37C 1F380-1F393 1F3A0-1F3C4
1F3C6-1F3CA 1F3E0-1F3F0 1F400-1F43E 1F440 1F442-1F4F7 1F4F9-1F4FC
1F500-1F53D 1F540-1F543 1F550-1F567 1F5FB-1F640 1F645-1F64F 1F680-1F6C5
1F700-1F773 E0001 E0020-E007F E0100-E01EF

正确的操作方法如下所示。

如果您打算使用Unicode字符属性,那么像这样硬编码代码点数是没有希望的。你真正想要的是能够像这样说:

[^'p{Script=Latin}'p{Script=Common}'p{Script=Inherited}]

然而,Javascript正则表达式在这方面仍然完全是千禧一代,并且到目前为止还不符合Unicode技术标准#18:Unicode正则表达式,即使在最基本的遵从级别,第一级:

级别1:基本Unicode支持。在这个级别,正则表达式引擎提供了对Unicode字符作为基本逻辑单元的支持。(这与Unicode实际序列化为UTF-8、UTF-16BE、UTF-16LE、UTF-32BE或UTF-32LE无关。)这是有用的Unicode支持的最低级别。它没有考虑到最终用户对字符支持的期望,但确实满足了大多数低级程序员的需求。此级别的正则表达式匹配的结果与国家或语言无关。在这个级别上,正则表达式引擎的用户需要编写更复杂的正则表达式来完成完整的Unicode处理。

因为即使是最基本的Unicode正则表达式遵从级别仍然远远低于Javascript的能力,所以我强烈建议在服务器上使用一些实际支持它们的语言运行任何您需要的Unicode感知正则表达式。

然而,如果这是不实际的,一个节省的工作是Javascript的XRegExp插件,它提供了一个更安全的正则表达式库,也允许访问某些必要的字符属性,如您正在尝试使用。

从v2.0开始,"XRegExp All"插件支持所有这些:

  • XRegExp 2.0.0
  • Unicode Base 1.0.0
  • Unicode Categories 1.2.0
  • Unicode Scripts 1.2.0
  • Unicode Blocks 1.2.0
  • Unicode Properties 1.0.0
  • XRegExp。matchRecursive 0.2.0
  • XRegExp。构建0.1.0
  • 原型1.0.0

这意味着一旦你加载了它,你就可以通过这种方式获得你需要的属性:

XRegExp("[^''p{Latin}''p{Common}''p{Inherited}]");

请仔细注意,从Unicode v6.2开始,以下任何和所有代码点和代码点范围都被认为具有Script=Latin字符属性:

0041-005A 
0061-007A 
00AA 
00BA 
00C0-00D6 
00D8-00F6 
00F8-02B8 
02E0-02E4 
1D00-1D25 
1D2C-1D5C 
1D62-1D65 
1D6B-1D77 
1D79-1DBE 
1E00-1EFF 
2071 
207F 
2090-209C 
212A-212B 
2132 
214E 
2160-2188 
2C60-2C7F 
A722-A787 
A78B-A78E 
A790-A793 
A7A0-A7AA 
A7F8-A7FF 
FB00-FB06 
FF21-FF3A 
FF41-FF5A 

然而这些是具有Script=Common字符属性的代码点:

0000-0040  
005B-0060  
007B-00A9  
00AB-00B9  
00BB-00BF  
00D7
00F7
02B9-02DF  
02E5-02E9  
02EC-02FF  
0374
037E
0385 
0387
0589
060C
061B
061F
0640
0660-0669  
06DD
0964-0965  
0E3F 
0FD5-0FD8  
10FB
16EB-16ED
1735-1736
1802-1803
1805
1CD3
1CE1
1CE9-1CEC
1CEE-1CF3
1CF5-1CF6
2000-200B
200E-2064
206A-2070  
2074-207E  
2080-208E  
20A0-20BA  
2100-2125
2127-2129
212C-2131  
2133-214D  
214F-215F  
2189
2190-23F3
2400-2426
2440-244A
2460-26FF
2701-27FF
2900-2B4C
2B50-2B59
2E00-2E3B
2FF0-2FFB  
3000-3004
3006
3008-3020
3030-3037  
303C-303F
309B-309C
30A0
30FB-30FC
3190-319F
31C0-31E3
3220-325F
327F-32CF
3358-33FF
4DC0-4DFF
A700-A721
A788-A78A
A830-A839
FD3E-FD3F  
FDFD
FE10-FE19  
FE30-FE52
FE54-FE66
FE68-FE6B  
FEFF
FF01-FF20  
FF3B-FF40
FF5B-FF65
FF70
FF9E-FF9F
FFE0-FFE6
FFE8-FFEE
FFF9-FFFD
10100-10102
10107-10133
10137-1013F
10190-1019B
101D0-101FC
1D000-1D0F5
1D100-1D126
1D129-1D166
1D16A-1D17A
1D183-1D184
1D18C-1D1A9
1D1AE-1D1DD
1D300-1D356
1D360-1D371
1D400-1D454
1D456-1D49C
1D49E-1D49F
1D4A2
1D4A5-1D4A6
1D4A9-1D4AC
1D4AE-1D4B9
1D4BB
1D4BD-1D4C3
1D4C5-1D505
1D507-1D50A
1D50D-1D514
1D516-1D51C
1D51E-1D539
1D53B-1D53E
1D540-1D544
1D546
1D54A-1D550
1D552-1D6A5
1D6A8-1D7CB
1D7CE-1D7FF
1F000-1F02B
1F030-1F093
1F0A0-1F0AE
1F0B1-1F0BE
1F0C1-1F0CF
1F0D1-1F0DF
1F100-1F10A
1F110-1F12E
1F130-1F16B
1F170-1F19A
1F1E6-1F1FF
1F201-1F202
1F210-1F23A
1F240-1F248
1F250-1F251
1F300-1F320
1F330-1F335
1F337-1F37C
1F380-1F393
1F3A0-1F3C4
1F3C6-1F3CA
1F3E0-1F3F0
1F400-1F43E
1F440
1F442-1F4F7
1F4F9-1F4FC
1F500-1F53D
1F540-1F543
1F550-1F567
1F5FB-1F640
1F645-1F64F
1F680-1F6C5
1F700-1F773
E0001
E0020-E007F

这些是具有Script=Inherited字符属性的代码点:

0300-036F
0485-0486
064B-0655
0670
0951-0952
1CD0-1CD2
1CD4-1CE0
1CE2-1CE8
1CED
1CF4
1DC0-1DE6
1DFC-1DFF
200C-200D
20D0-20F0
302A-302D
3099-309A
FE00-FE0F
FE20-FE26
101FD
1D167-1D169
1D17B-1D182
1D185-1D18B
1D1AA-1D1AD
E0100-E01EF

我希望使用像这样的文字代码点数字所带来的可怕的维护、维护、易读性和可写性问题使您清楚地知道,您至少要使用XRegExp附加组件。

我使用的是:

/^[A-z'u00C0-'u00ff's''.,-'/#!$%'^&'*;:{}='-_`~()]+$/

作为正则表达式。我没有测试过所有的选项,但我已经用了很多年了,从来没有出现过任何问题。

var regexp = /[A-z'u00C0-'u00ff]+/g,
  ascii = ' hello !@#$%^&*())_+=',
  latin = 'ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏàáâãäåæçèéêëìíîïÐÑÒÓÔÕÖØÙÚÛÜÝÞßðñòóôõöøùúûüýþÿ',
  chinese = ' 你 好 ';
console.log(regexp.test(ascii)); // true
console.log(regexp.test(latin)); // true
console.log(regexp.test(chinese)); // false

list: https://gist.github.com/germanattanasio/84cd25395688b7935182

一种可能的方法:

if (/[^'u0020-'u007F'u00A0-'u024F'u1E00-'u1EFF]/.test(value)) {
    // non latin characters found
}

正则表达式测试'u0020-'u007F'u00A0-'u024F'u1E00-'u1EFF组的[]中非^的字符。