如何在正则表达式中用标点符号检测汉字?

时间:2016-01-06 09:20:43

标签: javascript php regex unicode

我注意到有关如何用正则表达式检测汉字的问题。这些是我在stackoverflow上读到的一些问题:

Php check if the string has Chinese chars

detecting chinese characters in php string

还有一些文章在stackoverflow之外:

http://www.regular-expressions.info/unicode.html - unicode脚本

基本上他们建议使用\p{Han}+[\x{4e00}-\x{9fa5}]+.*来检测中文字符。有没有办法检测中文标点符号?

中文标点符号的一些示例(但不是全部): ?:“,”「」『』 - ()【】

4 个答案:

答案 0 :(得分:1)

  

有没有办法检测中文标点符号?

这是一个基本的Unicode属性正则表达式,仅用于获取标点符号。
它说只有在CJK块中时才获取所有\p{Han}脚本字符
用于符号和标点符号。

这可以有效过滤汉字符号和标点符号。

从Unicode 10开始,原来是这15个字符:々〇〡〢〣〤〥〦〧〨〩〸〹〺〻

\p{Han}(?<=\p{Block=CJK_Symbols_And_Punctuation})

如果您使用的引擎不支持 properties 或不支持
块符号,则可以使用生成的15个字符的类范围。

是其中之一

[\x{3005}\x{3007}\x{3021}-\x{3029}\x{3038}-\x{303B}]
[\u3005\u3007\u3021-\u3029\u3038-\u303B]

来源:http://www.regexformat.com UCD界面。

答案 1 :(得分:0)

您要匹配的大多数字符都可以匹配:

[\x{FF1F}-\x{FF2D}\x{FF01}-\x{FF1E}\x{3001}-\x{30AD}]+

答案 2 :(得分:0)

我建议通过查看Zhon来告知自己,这是一个Python库,提供中文文本处理中常用的常量。

幸运的是,hanzi.py包含了一个非常适合您需要的正则表达式的定义:

#: A regular expression pattern for a Chinese sentence. A sentence is defined
#: as a series of characters and non-stop punctuation marks followed by a stop
#: and zero or more container-closing punctuation marks (e.g. apostrophe or brackets).

sent = sentence = '[{characters}{radicals}{non_stops}]*{sentence_end}'.format(
    characters=characters, radicals=radicals, non_stops=non_stops,
    sentence_end=_sentence_end)

上面的定义导致以下正则表达式 *

[〇一-鿿㐀-䶿豈-﫿----⼀-⿕⺀-⻳"#$%&'()*+,-/:;<=>@[\]^_`{|}~⦅⦆「」、 、〃〈〉《》「」『』【】〔〕〖〗〘〙〚〛〜〝〞〟〰〾〿–—‘’‛“”„‟…‧﹏﹑﹔·]*[!?。。][」﹂”』’》)]}〕〗〙〛〉】]*

Code Example

preg_match_all('/[〇一-鿿㐀-䶿豈-﫿----⼀-⿕⺀-⻳"#$%&'()*+,-/:;<=>@[\]^_`{|}~⦅⦆「」、 、〃〈〉《》「」『』【】〔〕〖〗〘〙〚〛〜〝〞〟〰〾〿–—‘’‛“”„‟…‧﹏﹑﹔·]*[!?。。][」﹂”』’》)]}〕〗〙〛〉】]*/', "我的中文不好。我是意大利人。你知道吗?", $matches, PREG_SET_ORDER, 0);
var_dump($matches);

如果您更喜欢使用相关CJK表意文字Unicode块的字符代码范围,请参考我有linked的Python源代码,或者从下面的Javascript示例中获取它:

&#13;
&#13;
const regex = /[\u3007u4E00-\u9FFF\u3400-\u4DBF\uF900-\uFAFF\u20000-\u2A6DF\u2A700-\u2B73F\u2B740-\u2B81F\u0002F800-\u2FA1F\u2F00-\u2FD5\u2E80-\u2EF3\uFF02\uFF03\uFF04\uFF05\uFF06\uFF07\uFF08\uFF09\uFF0A\uFF0B\uFF0C\uFF0D\uFF0F\uFF1A\uFF1B\uFF1C\uFF1D\uFF1E\uFF20\uFF3B\uFF3C\uFF3D\uFF3E\uFF3F\uFF40\uFF5B\uFF5C\uFF5D\uFF5E\uFF5F\uFF60\uFF62\uFF63\uFF64\u3000\u3001\u3003\u3008\u3009\u300A\u300B\u300C\u300D\u300E\u300F\u3010\u3011\u3014\u3015\u3016\u3017\u3018\u3019\u301A\u301B\u301C\u301D\u301E\u301F\u3030\u303E\u303F\u2013\u2014\u2018\u2019\u201B\u201C\u201D\u201E\u201F\u2026\u2027\uFE4F\uFE51\uFE54\u00B7]*[\uFF01\uFF1F\uFF61\u3002][」﹂”』’》)]}〕〗〙〛〉】]*/gm;
const str = `我的中文不好。我是意大利人。你知道吗?`;
let m;

while ((m = regex.exec(str)) !== null) {
    // This is necessary to avoid infinite loops with zero-width matches
    if (m.index === regex.lastIndex) {
        regex.lastIndex++;
    }
    
    // The result can be accessed through the `m`-variable.
    m.forEach((match, groupIndex) => {
        console.log(`Found match, group ${groupIndex}: ${match}`);
    });
}
&#13;
&#13;
&#13;

PS:我也发现这个answer很有帮助。

答案 3 :(得分:0)

[\u4e00-\u9fa5]在VSCode中为我工作,其他建议的解决方案则没有。我在这里偶然发现了一个解决方案,该解决方案是一个在线正则表达式解释器:http://tool.chinaz.com/regex/