Java 正则表达式构建

标签 java regex

我需要帮助来构建以下模式的正则表达式,我必须以特定模式收集字符串。

示例输入字符串:

*!
hostname ${hostname} !
!
!
ip name-server ${ip-name-server}
no ipv6 cef
!
!
voice class codec 1 
 codec preference 1 ${codec-pref-1}  codec preference 2 ${codec-pref-2}      codec preference 3 ${codec-pref-3} !
!
session target dns:${session-targ-DNS}  dtmf-relay rtp-nte*

输出应该是 主机名, IP 名称服务器, 编解码器-pref-1, 编解码器-pref-2, 编解码器-pref-3, session 目标-DNS,

即应收集并检索格式为 ${string} 的字符串。

我尝试了如下代码

public void fetchKeyword(String inputString) {  
        String inputString1 = inputString.replace("\n", " ");   
        Pattern p = Pattern.compile("\\${$1} ");
        Matcher m = p.matcher(inputString1);
        int i=0;
        while(m.find()){
            System.out.println(m.group(i));
            i++;
        }
    }

我还尝试了 .${.*}(.)${.*?} 等模式,但没有达到预期的结果。我遇到了如下异常

  Exception in thread "main" java.util.regex.PatternSyntaxException: Illegal repetition near index 1
\${$1} 
 ^
    at java.util.regex.Pattern.error(Unknown Source)
    at java.util.regex.Pattern.closure(Unknown Source)
    at java.util.regex.Pattern.sequence(Unknown Source)
    at java.util.regex.Pattern.expr(Unknown Source)
    at java.util.regex.Pattern.compile(Unknown Source)
    at java.util.regex.Pattern.<init>(Unknown Source)
    at java.util.regex.Pattern.compile(Unknown Source)
    at myUtil.ReplaceString.fetchKeyword(ReplaceString.java:70)
    at myUtil.ReplaceString.main(ReplaceString.java:20)

有人可以帮忙吗?

最佳答案

您可以使用此解决方案来检索占位符文本:

// test string
String input = "! hostname ${hostname} ! ! ! ip name-server "
            + "${ip-name-server} no ipv6 cef ! ! "
            + "voice class codec 1 codec preference 1 ${codec-pref-1} "
            + "codec preference 2 ${codec-pref-2} codec preference 3 "
            + "${codec-pref-3} ! ! session target "
            + "dns:${session-targ-DNS} dtmf-relay rtp-nte";

// compiling pattern with one group representing the text inside ${}
Pattern p = Pattern.compile("\\$\\{(.+?)\\}");
// initializing matcher
Matcher m = p.matcher(input);
// iterating find
while (m.find()) {
    // back-referencing group 1 each find
    System.out.println(m.group(1));
}

输出

hostname
ip-name-server
codec-pref-1
codec-pref-2
codec-pref-3
session-targ-DNS

注释

  • $1您使用的习惯用法用于替换(即 String#replaceAll ),以反向引用索引组。
  • 索引组在您的模式中声明为 ()或者从 Java 7 开始,作为命名组:(?<name>X)
  • 组的索引是由模式中分组惯用语的出现来定义的,而不是像您想象的那样通过匹配的迭代来定义
  • 请参阅文档 here
  • 我作为示例显示的模式是双重转义 $ , {}字符
  • 还值得注意的是,它使用不情愿的量词 ( +? ) 来尽可能匹配直到下一个已知字符: }
  • 最后,如上所述,组 #1 在括号内定义,代表任何字符(直到结束 } )
  • 只要 ${something} 内没有出现换行符,输入文本中的换行符就不会对该模式的结果产生负面影响。习语
  • 如果发生这种情况,您需要在解析之前清理换行 rune 本,或者使用 Pattern.DOTALL 参数化您的模式。然后清理匹配中的换行符(不过后者看起来不是一个很好的解决方案)
  • Thomas提到,此模式假定您的表达式在 {} 之间永远不会为空。如果您确实有一个空表达式,则解析从空表达式开头到下一个非空表达式结尾(如果适用)的所有内容都会失败。因此,要么保证您没有空表达式,要么您想使用 .*?而不是.+? (另请参阅托马斯的回答)。

关于Java 正则表达式构建,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39612225/

相关文章:

regex - 如何将所有包含 IP 地址的 URL 重定向到我的 www 域?

c# - 用于字母和空格的 .NET RegEx

java - java下载的区别

java - Java 中的大数比较

java - 检测 GWT 中的离线和在线状态

java - `java.nio.file.Files.createFile` 是阻塞调用吗?

c++ - 生成的getters和setters代码格式

regex - R中的正则表达式。捕获特定字段

java - 如何制作将行分成单词的正则表达式

java - UTC 或本地时间与我的模式的区域偏移量?