Java 字符串中键/值对的正则表达式查找/替换

Java 字符串中键/值对的正则表达式查找/替换,java,regex,replace,key-value,Java,Regex,Replace,Key Value,我试图解决一个问题,即使用“userData”,它包含适合regex${parameter}的可能的可替换参数,并跳过其他形式,如$parameter,这会导致它缺少扭曲的括号。我还跟踪它可以在密钥映射(kvPairs)中找到的可替换的成功匹配。如果是这样的话,我只想警告一下 在userData字符串中,我还有一个参数,该参数被包含匹配项的值替换。我本以为这场比赛的位置不会被评估,但它抛出了一个例外: 总的来说,我的方法如何?我能改进一下吗 exception in thread "main"

我试图解决一个问题,即使用“userData”,它包含适合regex${parameter}的可能的可替换参数,并跳过其他形式,如$parameter,这会导致它缺少扭曲的括号。我还跟踪它可以在密钥映射(kvPairs)中找到的可替换的成功匹配。如果是这样的话,我只想警告一下

在userData字符串中,我还有一个参数,该参数被包含匹配项的值替换。我本以为这场比赛的位置不会被评估,但它抛出了一个例外:

总的来说,我的方法如何?我能改进一下吗

exception in thread "main" java.lang.IllegalArgumentException: No group with name {myVariable}
    at java.util.regex.Matcher.appendReplacement(Matcher.java:849)
    at java.util.regex.Matcher.replaceFirst(Matcher.java:1004)
    at 
utils.Regex.getKeyValueSubstitutedUserData(Regex.java:36)
    at utils.Regex.main(Regex.java:77)
我可能决定阻止这个。但我想知道这到底是为什么失败。是重置位置并重新评估比赛吗

package Utils;

import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Regex {

   public Regex() {}

   private String getKeyValueSubstitutedUserData(Map<String, String> kvPairs, String userData) {

       String patternToFind = "(\\$\\{)(.+?)(\\})";
       Pattern regex = Pattern.compile( patternToFind );

       Matcher match = regex.matcher( userData );
       Set<String> missingKeys = new LinkedHashSet<>();
       while ( match.find()) {

           String key2 = match.group(2);

           if ( key2 != null ) {

              String value = kvPairs.get( key2 );

              if ( value != null ) {
                  userData = match.replaceFirst( value );
                  match.reset( userData );
              }
              else {
                  // Found a missing variable
                  missingKeys.add( key2 );
              }
          }
      }


      return userData;
  }

  public static void main(String[] args) {

      Regex regexUtil = new Regex();

      Map<String, String> kvPairs = new HashMap<> ();
      kvPairs.put( "LOCALHOSTIP", "10.234.158.5" );
      kvPairs.put( "METADATA_POLL_FREQ" , "60");
      kvPairs.put( "router1_eth0_cidr" , "10.234.158.0/24");
      kvPairs.put( "router1_eth0_gateway" , "10.234.158.1");
      kvPairs.put( "router1_eth0_mac_addresss" , "fa:16:3e:6f:4a:c3");
      kvPairs.put( "EVENT_TYPE" , "BOOT");
      kvPairs.put( "testFIP" , "_FIP_router_eth0");
      kvPairs.put( "METADATA_TIMESTAMP" , "1");
      kvPairs.put( "vnfInstanceNumber" , "1");
      kvPairs.put( "TestFIPVIP" , "_FIP_VIP_router_eth0");
      kvPairs.put( "router1_eth0" , "10.234.158.5");
      kvPairs.put( "myVariable" , "193.167.1.1");
      kvPairs.put( "HOSTNAME" , "router1");
      kvPairs.put( "METADATA_SCRIPT" , "erg");
      kvPairs.put( "_FIP_router1_eth0" , "10.2.31.42");
      kvPairs.put( "LOCALHOST" , "router1");
      kvPairs.put( "testVIP" , "_VIP_router_eth0");
      kvPairs.put( "HOSTNAMEIP" , "10.234.158.5");
      kvPairs.put( "TestNesting" , "${myVariable}");

      String userData = "abcShell script \n${HOSTNAMEIP} blah blah \n ${\nrouter1_eth0_gateway} ${HOSTNAME} $HOSTNAME ${EVENT_TYPE} ${foobar} ${TestNesting} ${_FIP_router1_eth0}";

      regexUtil.getKeyValueSubstitutedUserData( kvPairs, userData);

    }
}
package-Utils;
导入java.util.HashMap;
导入java.util.LinkedHashSet;
导入java.util.Map;
导入java.util.Set;
导入java.util.regex.Matcher;
导入java.util.regex.Pattern;
公共类正则表达式{
公共正则表达式(){}
私有字符串GetKeyValueSubstituteUserData(映射kvPairs、字符串userData){
字符串patternToFind=“(\\$\{)(.+?)(\\})”;
Pattern regex=Pattern.compile(patternToFind);
Matcher match=regex.Matcher(userData);
Set missingKeys=new LinkedHashSet();
while(match.find()){
字符串key2=match.group(2);
如果(键2!=null){
字符串值=kvPairs.get(键2);
if(值!=null){
userData=match.replaceFirst(值);
match.reset(用户数据);
}
否则{
//找到缺少的变量
丢失键。添加(键2);
}
}
}
返回用户数据;
}
公共静态void main(字符串[]args){
Regex regexUtil=new Regex();
Map kvPairs=newhashmap();
kvPairs.put(“LOCALHOSTIP”,“10.234.158.5”);
kvPairs.put(“元数据轮询频率”,“60”);
kvPairs.put(“路由1_eth0_cidr”,“10.234.158.0/24”);
kvPairs.put(“路由1_eth0_网关”,“10.234.158.1”);
kvPairs.put(“路由1_eth0_mac_地址”,“fa:16:3e:6f:4a:c3”);
kvPairs.put(“事件类型”、“引导”);
kvPairs.put(“testFIP”,“FIP”路由器“eth0”);
kvPairs.put(“元数据\时间戳”,“1”);
kvPairs.put(“vnfInstanceNumber”,“1”);
kvPairs.put(“TestFIPVIP”,“FIP\VIP\urouter\ueth0”);
kvPairs.put(“路由器1_eth0”、“10.234.158.5”);
kvPairs.put(“myVariable”、“193.167.1.1”);
输入(“主机名”、“路由1”);
put(“元数据脚本”、“erg”);
kvPairs.put(“_FIP_router1_eth0”,“10.2.31.42”);
kvPairs.put(“LOCALHOST”、“router1”);
kvPairs.put(“testVIP”,“VIP”路由器“\u eth0”);
kvPairs.put(“主机名IP”、“10.234.158.5”);
put(“TestNesting”,“${myVariable}”);
String userData=“abcShell script\n${HOSTNAMEIP}blah blah\n${\nrouter1_eth0_gateway}${HOSTNAME}$HOSTNAME${EVENT_TYPE}${foobar}${TestNesting}${FIP_router1_eth0}”;
regexUtil.getKeyValueSubstituteUserData(kvPairs,userData);
}
}

谁是Brian,你为什么要感谢他?是我,我感谢那些回答我的人。在问题描述中我们并不需要:)更多信息可以在替换部分中使用,
${name}
访问命名捕获组的内容,如
(?:\\w+)