Javascript 用于日语、英语标签(如Twitter)的正则表达式

Javascript 用于日语、英语标签(如Twitter)的正则表达式,javascript,regex,unicode,cjk,Javascript,Regex,Unicode,Cjk,目前,我正在使用这个正则表达式来检测日语和英语标签 \B([##][·・ー_0-90-9字母a-zA-Zぁ-んァ-ン一-龠]{1,24})(?=\W |$) 规则是: Hashtag must be started with # character. Hashtag will be detected by space character and other special characters (!,@,&,*,%,$). Example 1: Hello#guys. This is a

目前,我正在使用这个正则表达式来检测日语和英语标签

\B([##][·・ー_0-90-9字母a-zA-Zぁ-んァ-ン一-龠]{1,24})(?=\W |$)

规则是:

Hashtag must be started with # character.
Hashtag will be detected by space character and other special characters (!,@,&,*,%,$).
Example 1: Hello#guys. This is a #test. -> Valid hashtag: #test.
Example 2: Hello#guys. This is a #test!#message. -> Valid hashtag: #test and #message
Example 3: Hello#guys. This is a #test #message. -> Valid hashtag: #test and #message
Example 4: Hello#guys. This is a #test#message. -> Valid hashtag: #test
Example 5: #asdasdasdasdasdasdasdasdasd -> Valid hashtag: none
Example 6: # -> Valid hashtag: none
到目前为止,它一直有效,直到我遇到了这两个带有日语字符的具体案例:(

#日本語#asd=>有效的标签应为#日本語

#日本語日本語日本語日本語日本語日本語日本語日本語日本語=>将不是有效的标签

上面的正则表达式无法检测这两种情况,我尝试了很多方法,但至今没有找到任何解决方案

目前,我正在使用此网站进行测试:

请帮忙,提前谢谢


感谢@Ryszard捷克语

最终的解决方案是,这将完全像Twitter标签一样工作:

/(


测试:

我认为问题在于Javascript正则表达式引擎的局限性。当我在Perl中使用您的正则表达式和文本时,所有内容都与您期望的匹配。当我在regexr.com上尝试时,我得到了错误的匹配。做了一些测试后,它无法将汉字识别为单词字符,而且似乎
\B
已损坏

如果您只是尝试匹配
\w
\w
,您将看到它认为单词和非单词是什么

如果更换
#日本語#asd
#日本語x#asd
它将排除
#asd
語#
都被视为非单词字符,因此
\B
匹配

如果您尝试匹配
\B.
\B.
您将看到它认为是连续的和非连续的所有字符对。但是请注意,您需要在具有偶数个字符的行中进行尝试,所以请进行前置和后置填充以查看所有组合。
e、 g.
foo
foo
foo

我认为修复
\B
行为的唯一方法是使用负面的look-behind,但该站点不支持它

如果将
\W
替换为
[^·・ー_0-90-9字母a-zA-Zぁ-んァ-ン一-龠],它将排除太长的匹配

我的建议是在Perl中这样做,它有绝对最好的正则表达式

这是文件

下面是我在Perl中所做的

使用严格;
使用诊断;
使用utf8;
双模式标准输出':utf8';
我们的@s=split/\n/,
“大家好,这是一个测试。
大家好,这是一条“测试”信息。
大家好,这是一条“测试”信息。
大家好,这是一条“测试”信息。
#ASDASDASDASDASDA27
# 
#日本語#自闭症
#日本語日本語日本語日本語日本語日本語日本語日本語日本語 27
#日本語日本語日本語日本語日本語日本語日本語日本語 24
#日本語日本語日本語日本語日本語日本語日本語日本語x25
';
我们的$re=qr{\B([##][·・ー_0-90-9字母a-zA-Zぁ-んァ-ン一-龠]{1,24})(?=\W |$)};
foreach我的$s(@s){
打印“字符串\“$s\”:\n”;
打印联接“\n”,($s=~m/$re/g),”;
打印“\n”;
}
其中打印:

String "Hello#guys. This is a #test.": #test String "Hello#guys. This is a #test!#message.": #test #message String "Hello#guys. This is a #test #message.": #test #message String "Hello#guys. This is a #test#message.": #test String "#asdasdasdasdasdasdasdasdasd 27": String "# ": String "#日本語#asd": #日本語 String "#日本語日本語日本語日本語日本語日本語日本語日本語日本語 27": String "#日本語日本語日本語日本語日本語日本語日本語日本語 24": #日本語日本語日本語日本語日本語日本語日本語日本語 String "#日本語日本語日本語日本語日本語日本語日本語日本語x 25": 字符串“大家好,这是一个测试”: #试验 字符串“大家好,这是一条测试消息。”: #试验 #信息 字符串“大家好,这是一条测试消息。”: #试验 #信息 字符串“大家好,这是一条测试消息。”: #试验 字符串“#asdasdasd 27”: 字符串“#”: “字符串”#日本語#建筑署∶ #日本語 “字符串”#日本語日本語日本語日本語日本語日本語日本語日本語日本語 27": “字符串”#日本語日本語日本語日本語日本語日本語日本語日本語 24": #日本語日本語日本語日本語日本語日本語日本語日本語 “字符串”#日本語日本語日本語日本語日本語日本語日本語日本語x 25“: 嗯


(我删除了我的第一个答案,因为我意识到它是错误的。)

使用Unicode属性,您可以将
\B
模式重新定义为
(?![\p{L}0-9])并使用

/(?
看

JavaScript代码片段

大家好,这是一个测试。大家好。这是一个测试!消息。大家好。这是一个测试消息。大家好。这是一个测试消息。大家好。这是一个测试消息。大家好。这是一个测试消息。大家好。这是一个测试消息#日本語#自闭症#日本語日本語日本語日本語日本語日本語日本語日本語日本語";
console.log(string.match(/)我试过了。我只处理了第二个案例。\B([##][·・ー_0-90-9字母a-zA-Zぁ-ゔァ-ンァ-ン゙゚一-龯々〆〤]{1,24})(?=[^·・ー_0-90-9字母a-zA-Zぁ-ゔァ-ンァ-ン゙゚一-龯々〆〤]|$) 由于日语字符被视为“非单词”,因此\B和| W不能按预期工作。感谢您的帮助,我找到了此解决方案
(?但是@Ryszard Czech的解决方案看起来很简洁,因此我将跟随他:D@little_Friend无论采用哪种方法,都可以用否定的眼光来修正
\B
。)