【问题标题】:Any way to use a regular expression with two different pairs of delimiters?有什么方法可以使用带有两对不同分隔符的正则表达式?
【发布时间】:2016-08-18 15:58:58
【问题描述】:

我已经在我的 Android 应用程序中添加了表情符号,并且我一直在使用 Java 中的 Regex,因此分配给它们的代码将匹配正则表达式(其中包含一对要使用的分隔符),从而使字符显示为图像。

一些表情符号代码是,例如,sadhappysmile

到目前为止,情况是这样的:

  • 分隔符:()

  • 正则表达式:\\(([.[^\\(\\)]]+)\\)

  • 匹配的表情符号代码示例:(sad)(happy)(smile)

我注意到,对于我添加的一些新表情符号,用户使用另一对分隔符键入代码会更实用,例如字母 z,。那么,第二种情况是这样的:

  • 分隔符:z,

  • 正则表达式:z([.[^z\\,]]+)\\,

  • 匹配的表情符号代码示例:zsad,zhappy,zsmile,

然后,我想要的是合并这两个正则表达式,这样用户就可以使用两对分隔符中的任何一个输入表情符号代码,无论他或她喜欢哪个,它都会匹配。例如,sad 表情符号将被匹配,并且每次写成(sad)zsad, 时都会显示为图像,例如:

嗨。 (悲伤)我有坏消息。 zsad,

嘿... (悲伤)

好的。再见。 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 中将反斜杠加倍,当然,这个可以在 online Java regex tester 处使用)。检查this demo
  • 顺便说一句,为什么你的图案中有一个点?
  • 我将我的评论转化为答案。

标签: java regex delimiter regex-lookarounds regex-alternation


【解决方案1】:

我可能会去

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

我发现它更简单,并且作为您自己的尝试,只需捕获实际的令牌。 \w 也允许在令牌中使用数字和下划线,我不知道您是否认为这是一个加号,但应该不会是一个缺点(?)。

所以作为一个java字符串:

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

Check it out here, at regex101.

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

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

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

问候

【讨论】:

  • 我喜欢你最初的正则表达式。如果想匹配 just 令牌,可以使用环视,这将避免处理 2 个捕获的组(整个匹配是令牌):(?<=\()\w+(?=\))|(?<=z)\w+(?=,)
【解决方案2】:

你可以这样使用:

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

这是example

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

要匹配消息中的多个 1,请使用 global,这可能是必需的,它包含在示例链接中。它与您在我找到的 3 个单独的 Java 正则表达式测试器上提供的句子相匹配。

编辑

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

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

【讨论】:

    【解决方案3】:

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

    所以,使用这个正则表达式:

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

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

    检查只处理匹配值this demo

    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,>>
    

    【讨论】:

      猜你喜欢
      • 2017-02-10
      • 2011-07-26
      • 1970-01-01
      • 1970-01-01
      • 2014-06-06
      • 2021-12-27
      • 2020-09-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多