我使用Ruby 1.8.7 我有一个在Ruby 1.8.7中有效的正则表达式来匹配所有表情符号
/\|?>?[:*;Xx8=<(%)D]-?'?,?o?\_^?[-DOo0S*Ppb3c:;\/\\|)(}{\]><]\)?|\(/
但是,我希望匹配除此正则表达式之外的所有符号集 例如,以下字符串
hi =as.) friend:) haha yay! ;) =) (test test) R&R I.O.U. :> :} :{ :< :< =) :S ;o) >:) :-| :| :o :*) %-( )-: ): )o: 8-0 8/ 8\ 8c :'( :'-( :( :*( :,( :-( :-/ :-S :-\ :-| :/ :O :S :\ :| =( >:( D: (o; 8-) ;) ;o) %-) (-: (: (o: 8) :) :-D :-P :D :P :P :] :o) :p <3 =) =] >:) >:D >=D
我需要它来匹配
= .) () & . . .
请参阅 - http://rubular.com/r/QpteIutq3B
我怎样才能做到这一点?
答案 0 :(得分:1)
我认为这与正则表达式相关是一项非常困难的任务。
我的第一个想法是在匹配符号之前使用负前瞻断言(匹配表情符号),例如
(?!\|?>?[:*;Xx8=<(%)D]-?'?,?o?\_?[-DOo0S*Ppb3c:;\/\\|)(}{\]><]\)?|\()[:;._()]
# works like "if no emoticon at this position, then match a symbol"
,但这不起作用。 (See demo.) 这部分是因为你的模式检测到许多误报(匹配没有表情符号的东西),但它也有一个基本问题:它与表情符号中的第一个字符不匹配,但它将匹配表情符号的其余部分。也许一个更有经验的正则表达式用户可以使用花哨的正则表达式魔术来完成这项工作。
所有这一切,我只能想到一种方式:
对于要匹配的每个字符,请使用lookbehind和lookahead断言以确保它不是任何表情符号的一部分。这是很多的工作。例如,为了匹配字符=:;
,我提出了以下模式:
(?<![(){}\[\]<>|D])(?<![(){}\[\]<>|][o-])[=:;](?!'?[o*,-]?[(){}\[\]<>|PpD\\\/OSso0])
基本思想是这样的:人物=:;
通常用作表情符号的眼睛。因此,我们必须断言左侧或右侧没有(可选)鼻子o*,-
且没有嘴(){}[]<>|PpD\/OSso0
。更糟糕的是,lookbehind断言不允许量词,因此重复(?<![(){}\[\]<>|D])
和(?<![(){}\[\]<>|][o-])
(其中一个匹配嘴,而另一个匹配嘴和鼻子)。
构建匹配所有特殊字符的完整模式需要付出很多努力,并且它可能会非常长且令人困惑。
如果您没有被迫使用纯正则表达式执行此操作,我建议使用正则表达式从字符串中删除所有表情符号,然后查找所有剩余的符号。
P.S。我制作了这个模式以匹配表情符号,它可以很好地适应旋转的笑脸,如:x
,>:|
,(:
等。它也应该产生比你的模式更少的误报。
更新#2:模式不再匹配数字。增加了对东部笑脸的支持。其他小改进。现在匹配相当数量的Wikipedia's list of emoticons。 (See demo)
(?!\d\d)(?![a-zA-Z]{2})(?:(?:>?[:;=%8BXx]['‘’]?[-o*,^っ]?(?:(?P<mouth>[()|Il])(?P=mouth)*|[\/0\]o\\D\[PpSs<>{}CcOXx*3@ÞþbL&?$#]))|(?:[()\\{}\/<\[>\]DOo0|SsXxlI*@q][-o*,]?['‘’]?[:=8;%Xx]<?))|(?P<head>\()?(?:(?P<eye>[<>v*.^~=ಠ-])?[_.-](?P=eye)|[o0O][_.-][o0O]|>[_.-]?<)['‘’]?(?(head)\))|xD|XD|XP|xP|DX|<3|\^\^|\\o\/|o\/|\\o