有没有一种方法可以使用两个不同的定界符对正则表达式进行匹配?

3
我已经在我的Android应用程序中添加了表情符号,并且一直在使用Java中的正则表达式,所以分配给它们的代码将匹配正则表达式(其中包含要用于的一对分隔符),使字符显示为图像。
例如,一些表情符号代码是"sad"、"happy"、"smile"等。
到目前为止,它是这样的:
- 分隔符:(和) - 正则表达式:\(([.[^\(\)]]+)\) - 匹配的表情符号代码示例:(sad)、(happy)、(smile)
我注意到,对于我添加的一些新表情符号,用户使用另一对分隔符——如字母z和逗号来输入它们的代码会更实用。那么,第二种情况会像这样:
- 分隔符:z和, - 正则表达式:z([.[^z\\,]]+)\, - 匹配的表情符号代码示例:zsad,zhappy,zsmile 因此,我想把这两个正则表达式合并起来,这样用户就可以使用任意一对分隔符来输入表情符号代码,无论他或她喜欢哪一个,都可以匹配上。例如,每次写成"(sad)"或"zsad,"时,“sad”表情符号都会匹配并显示为图像,就像这样:
Hi. (sad) I've got bad news. zsad, Hey... (sad) Okay. Bye. zsad,
我尝试使用选择运算符和向前查看,但没有成功。在以下两个正则表达式中,我只匹配了选择器"|"左侧的内容(当然我希望能够匹配左右两侧的内容):
- \(([.[^\(\)]]+)\)|z([.[^z\\,]]+)\,
- z([.[^z\\,]]+)\,|\(([.[^\(\)]]+)\)
而在以下正则表达式中,我根本没有找到匹配项:

(\\(([.[^\\(\\)]]+)\\)|z([.[^z\\,]]+)\\,)(\\(([.[^\\(\\)]]+)\\))|(z([.[^z\\,]]+)\\,)

(z([.[^z\\,]]+)\\,|\\(([.[^\\(\\)]]+)\\))(z([.[^z\\,]]+)\\,)|(\\(([.[^\\(\\)]]+)\\))

\\(|z([.[^\\(\\z\\,)]]+)\\)|\\,(\\(|z)([.[^\\(\\z\\,)]]+)(\\)|\\,) (\\()|(z)([.[^\\(\\z\\,)]]+)(\\))|(\\,)

(?=\\(([.[^\\(\\)]]+)\\))(?=z([.[^z\\,]]+)\\,)(?=.*\\(([.[^\\(\\)]]+)\\))(?=.*z([.[^z\\,]]+)\\,)

很抱歉,这是一段庞大的文本。我只是想尽可能提供更多细节。有人知道我做错了什么或写错了什么,以及应该使用哪个正则表达式才能同时匹配“zemojicode,”和“(emojicode)”吗?非常感谢您的帮助。

Java不允许您为捕获组使用重复名称,也不支持分支重置和条件表达式。您需要使用替代,然后根据需要处理匹配项:\(([.[^()]]+)\)|z([.[^z,]]+),(当然,在Java中要将反斜杠加倍,这可以在在线Java正则表达式测试器中使用)。请查看此演示 - Wiktor Stribiżew
顺便问一下,你的模式中为什么有一个点? - Wiktor Stribiżew
我将我的评论转换为了答案。 - Wiktor Stribiżew
3个回答

1

我可能会选择

\((\w+)\)|z(\w+),

我发现这种方法更简单,和您自己的尝试一样,只需捕获实际标记即可。 \w 允许在标记中包含数字和下划线,这可能是一个优点,但不应该是缺点(?)。

因此,作为Java字符串:

 \\((\\w+)\\)|z(\\w+),

在regex101上查看

作为替代方案,我想提到这个:

[(z](\w+)[),]

这个更简单,但没有内置的语法检查。换句话说,它允许使用分隔符的组合,例如(sad,和zhappy),这可能被认为是一个缺点。
问候

我喜欢你最初的正则表达式。如果想要匹配仅仅这个标记,可以使用环视,这样就避免了处理2个捕获组(整个匹配是标记):(?<=\()\w+(?=\))|(?<=z)\w+(?=,) - Bohemian

0
你可以使用类似这样的代码:
(z[a-zA-Z]*,|\([a-zA-Z]*\))

这里是示例

它将捕获z<anylettershere>,或者(<anylettershere>)

为了匹配消息中的多个内容,使用global,这可能是必需的,并且在示例链接中已包含。它可以匹配您提供的句子,在我找到的3个不同的Java正则表达式测试器中都可以。

编辑

请注意,任何\字符都可能需要加倍。我主要使用PHP而不是Java,所以对此不是很了解,但给出的示例将变成:

(z[a-zA-Z]*,|\\([a-zA-Z]*\\))

0

Java不允许您为捕获组使用重复名称,也没有分支重置支持,也没有条件表达式。您需要使用交替然后根据您需要处理的匹配方式进行操作。

因此,请使用此正则表达式:

\(([.[^()]]+)\)|z([.[^z,]]+),

在Java代码中不要忘记双倍反斜杠。

检查此演示,它仅处理匹配值

String s = "Hi. (sad) I've got bad news. zsad,\nHey... (sad)\nOkay. Bye. zsad,";
System.out.println(s.replaceAll("\\(([.[^()]]+)\\)|z([.[^z,]]+),", "<<$0>>")); 

输出:

Hi. <<(sad)>> I've got bad news. <<zsad,>>
Hey... <<(sad)>>
Okay. Bye. <<zsad,>>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接