捕捉汉字的JavaScript正则表达式

捕捉汉字的JavaScript正则表达式,javascript,regex,unicode,Javascript,Regex,Unicode,我不能让这个javascript函数以我想要的方式工作 //匹配包含汉字和/或假名字符的字符串 如果字符串由汉字和/或假名字符组成,则返回TRUE;如果存在字母或其他字符,则返回FALSE 我希望它返回至少1个汉字和/或假名字符,而不是所有汉字和/或假名字符 提前感谢您的帮助 /[\u4E00-\u9FAF|\u3040-\u3096|\u30A1-\u30FA|\uFF66-\uFF9D|\u31F0-\u31FF]/ 不要用$^将其锚定到字符串的开头和结尾,在这种情况下,+是无用的。正确的

我不能让这个javascript函数以我想要的方式工作

//匹配包含汉字和/或假名字符的字符串

如果字符串由汉字和/或假名字符组成,则返回TRUE;如果存在字母或其他字符,则返回FALSE

我希望它返回至少1个汉字和/或假名字符,而不是所有汉字和/或假名字符

提前感谢您的帮助

/[\u4E00-\u9FAF|\u3040-\u3096|\u30A1-\u30FA|\uFF66-\uFF9D|\u31F0-\u31FF]/
不要用
$^
将其锚定到字符串的开头和结尾,在这种情况下,
+
是无用的。

正确的答案不是硬编码范围。永远不要在你的代码里放魔法数字!这是一场维护噩梦。它很难读,很难写,很难调试,很难维护。你怎么知道你的号码是对的?当他们添加新的时会发生什么?不,不要使用幻数。求你了

正确的答案是使用命名的Unicode脚本,这是每个Unicode代码点的基本方面:

[\p{Han}\p{Hiragana}\p{Katakana}]
这就需要使用Javascript

真正的问题是Javascript正则表达式本身太原始,不支持Unicode属性,因此也不支持Unicode。也许这在15年前曾经是一个可以接受的妥协,但今天,正如你们自己所发现的,这完全是一种无法容忍的疏忽


在新的
脚本扩展
属性中,您还将丢失一些指定为假名的
公共
代码点,但可能没有关系。您可以将
\p{Common}
添加到上面的集合中。

既然Unicode属性转义是ES(2018)规范的一部分,那么如果JS引擎支持此功能(在@tchrist的答案上展开),则可以本机使用以下正则表达式:

如果要从匹配中排除标点符号:

/(?!\p{Punctuation})[\p{Script_Extensions=Han}\p{Script_Extensions=Hiragana}\p{Script_Extensions=Katakana}]/u
  • 日文标点符号:
    [\u3000-\u303f]
  • 平假名:
    [\u3040-\u309f]
  • 片假名:
    [\u30a0-\u30ff]
  • 罗马字符+半宽片假名:
    [\uff00-\uffef]
  • 汉字:
    [\u4e00-\u9faf]|[\u3400-\u4dbf]

    • 为什么不只是这个?当它至少包含一个汉字时,将返回true

      /[一-龯]/.test(str)
      

      对不起:-(粘贴错误:-(我已回滚,希望一切正常。谢谢!:)我最终不理解$1,而是将注意力集中在^1上,因此他应该信任
      XRegExp
      (这将做完全相同的硬代码编号)?嗯…最后一个版本是2010-03-24,最后一个博客条目是2010-07-05…不,他做了正确的事情:他创建了一个具有正确名称和扩展字符串的方法。添加对另一个库的引用通常是一场噩梦。抱歉,但tchrist是对的。确实,最终,不知何故,会有databa这是不可避免的,但除非您的专业是维护unicode属性的数据库,否则您不想编写自己的函数。即使编写了,数字范围至少应来自配置文件。数字范围的硬编码只会导致错误。unicode数据库的新版本定期发布,并进行更改、ERATA等(另外,请注意,在许多情况下,95%有效的东西比没有更糟糕)。XRegExp的类别(如
      \p{Han}
      等)编译为常规JavaScript regexp。以下是
      Han
      的本机JavaScript regexp:
      /[U20\U20\U20\U20\U20\U20.80-\UU20\U20\U20\U20\U30 7\u3021-\u3029\u3029\U30\U30\U80-\U20\UU20\U20\U20\U20.80-\U20\U20.U20-\U20\U2.U20-\UUUU20-\U20\UU20.0-\UUU20-\UUU20-\UU20-\U20\UU20-\U20\UU20\UU20-\U2.0\U20\UU20-\UU20-\UU20-\UU20-\UU20\U20\UU20\UU20\UUUU2.0\\uuuuuuuuuuuuuuuuuuuuuuu20-\黏黏黏黏黏黏黏黏对于平假名:
      /[\u3041-\u3096\u309D-\u309F]/
      。请原谅我没有在这里包括
      \p{Common}
      ,因为它对于这个评论框来说太大了。XRegExp的Han类别:
      XRegExp('\\p{Han}')
      现在简化了:
      /[⺀-⺙⺛-⻳⼀-⿕々〇〡-〩〸-〻㐀-䶵一-鿕豈-舘並-龎]/
      当我需要获取XRegExp的原始Han范围时,我总是会重新访问它,但最近,当粘贴到Chrome/Node时,上面的regexp无法编译。因此,我将regexp的
      字符串插入以获取以下内容:
      var-hanRegexp=/[\u2E80-\u2E99\u2E9B-\u2EF3\u2F00-\u2FD5\u3005\u3007\u3021-\u3029\u3038-\u303B\u3400-\u4DB5\u4E00-\u9FEF\uF900-\uFA6D\uFA70-\uFAD9]/;hanRegexp.test('山')从这里复制粘贴时将产生预期的结果(但你应该自己这样做以确保我没有骗你)。–Ahmed Fasih 19分钟的发言,尽管XRegExp似乎比当前的JavaScript
      Han
      脚本扩展更严格。请考虑:
      '三、四十?!ー'.匹配(/[\p{Script\u Extensions=Han}]/ug)
      产生四个结果,
      [”三", "、", "四", "十" ]。由于某种原因,包含了日语逗号。XRegExp版本只产生三个结果:
      '三、四十?!'.匹配(/[\u2E80-\u2E99\u2E9B-\u2EF3\u2F00-\u2FD5\u3005\u3007\u3021-\u3029\u3038-\u303B\u3400-\u4DB5\u4E00-\u9FEF\uF900-\uFA6D\uFA70-\uFAD9]/g)
      返回“三", "四", "十" ]`所以。简而言之,脚本总是很难编写的,无论您使用什么,您都可能会遇到奇怪的事情。XRegExp使用
      脚本
      属性,这对于
      ,意味着该字符在多个脚本中使用。这对于共享的任何其他字符来说都是一样的。
      脚本扩展实际上告诉您这些脚本是什么是。看了之后,它看起来像是在使用
      脚本
      (模仿XRegExp)除了标点符号之外,脚本扩展将排除一些特殊的汉字。也许这是一个可以接受的折衷。我还应该注意,您可以使用
      General\u Category
      属性排除标点符号,这可能是最好的方法
      /[\p{Script_Extensions=Han}\p{Script_Extensions=Hiragana}\p{Script_Extensions=Katakana}]/u
      
      /(?!\p{Punctuation})[\p{Script_Extensions=Han}\p{Script_Extensions=Hiragana}\p{Script_Extensions=Katakana}]/u
      
      /[\u3000-\u303f]|[\u3040-\u309f]|[\u30a0-\u30ff]|[\uff00-\uffef]|[\u4e00-\u9faf]|[\u3400-\u4dbf]/
      
      /[一-龯]/.test(str)