【问题标题】:Java and regex lexerJava 和正则表达式词法分析器
【发布时间】:2020-07-29 16:32:23
【问题描述】:

我正在尝试使用正则表达式为我正在制作的自定义降价“语言”在 Java 中制作某种 Lexer,这是我第一次使用这些东西,所以在一些事情上有点迷失。
其中一个可能的语法示例是:
Some <#000000>*text* [<#ffffff>Some more](action: Other <#gradient>text) and **finally** some more <#000>text!
我能够捕捉到一些东西,例如我使用(?<hex><#\w+>) 来捕捉“十六进制”和(?<action>\[[^]]*]\([^]]*\)) 来获取整个“动作”块。
我的问题是能够将它们全部捕获在一起,例如如何将它们组合在一起。例如,词法分析器需要输出如下内容:

TEXT - Some
HEX - <#000000>
TEXT - *text*
ACTION - [<#ffffff>Some more](action: Other <#gradient>text)
TEXT - and **finally** some more
HEX - <#000>
TEXT - text!

我稍后会处理粗体和斜体。
想要一些关于如何结合所有这些的建议!

【问题讨论】:

  • 您可以为所有部分创建(命名)捕获组^(.*?) (?&lt;hex1&gt;&lt;#\w+&gt;)(\*[^*]*\*) (?&lt;action&gt;\[[^]]*]\([^]]*\)) (.*?) (?&lt;hex2&gt;&lt;#\w+&gt;)(.*)$regex101.com/r/iocBCR/1
  • @Thefourthbird 嘿,谢谢!很难,这意味着它需要与我发送的示例完全相同?例如更改顺序或添加新标签将无法识别。
  • 当前模式取决于按该顺序出现的所有部分。您可以使用交替使其更灵活(?&lt;hex&gt;&lt;#\w+&gt;)|(?&lt;action&gt;\[[^]]*]\([^]]*\))|(?&lt;text&gt;[\w!* ]+)regex101.com/r/JWHNP9/1
  • @Thefourthbird 哦,好的,我现在开始明白了,谢谢!如果您想将其发布为答案。

标签: java regex lexer


【解决方案1】:

一个选项可以使用与每个单独部分匹配的替代,对于文本部分,例如使用 character class [\w!* ]+

在 Java 中,您可以检查捕获组的名称。

(?<hex><#\w+>)|(?<action>\[[^]]*]\([^]]*\))|(?<text>[\w!* ]+)

说明

  • (?&lt;hex&gt;&lt;#\w+&gt;)捕获组hex,匹配#和1+字字符
  • |或者
  • (?&lt;action&gt;捕获组action
    • \[[^]]*]\([^]]*\) 匹配 [...] 后跟 (...)
  • )关闭群
  • |或者
  • (?&lt;text&gt;[\w!* ]+)捕获组text,匹配字符类中列出的任何字符的1+次

Regex demo | Java demo

示例代码:

String regex = "(?<hex><#\\w+>)|(?<action>\\[[^]]*]\\([^]]*\\))|(?<text>[\\w!* ]+)";
String string = "Some <#000000>*text* [<#ffffff>Some more](action: Other <#gradient>text) and **finally** some more <#000>text!";

Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(string);

while (matcher.find()) {
    if (matcher.group("hex") != null) {
        System.out.println("HEX - " + matcher.group("hex"));    
    }
    if (matcher.group("text") != null) {
        System.out.println("TEXT - " + matcher.group("text"));  
    }
    if (matcher.group("action") != null) {
        System.out.println("ACTION - " + matcher.group("action"));  
    }
}

输出

TEXT - Some 
HEX - <#000000>
TEXT - *text* 
ACTION - [<#ffffff>Some more](action: Other <#gradient>text)
TEXT -  and **finally** some more 
HEX - <#000>
TEXT - text!

【讨论】:

    【解决方案2】:

    您可以像这样使用 Regex- Capturing groups 来实现这一点 ^(.*?) (?&lt;hex1&gt;&lt;#\w+&gt;)(\*[^*]*\*) (?&lt;action&gt;\[[^]]*]\([^]]*\)) (.*?) (?&lt;hex2&gt;&lt;#\w+&gt;)(.*)$ 为了更好地理解,请参阅Click here

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-28
      相关资源
      最近更新 更多