【问题标题】:Search for a substring between special character in a string在字符串中的特殊字符之间搜索子字符串
【发布时间】:2011-12-16 13:40:37
【问题描述】:

我有一个类似

的字符串
(&(objectclass=${abc})(uid=${xyz}))

如何搜索 ${abc}${xyz} 并替换为其他字符串。可以有任意数量的出现这样的子字符串,即主字符串中的${abc}。我在想string.indexOf(,但这可能会很乱。有什么最好的方法吗?

${abc} 将被另一个字符串 abc 替换。我会从其他一些参数中得到它们。

【问题讨论】:

  • 你想用什么替换?你有什么地图可以替换吗?
  • 用简单的字符串替换。 ${abc} 将被另一个字符串 abc 替换
  • 是的,但是你从哪里得到这些字符串?
  • 来自一些参数。它们可以为空。

标签: java regex string replace


【解决方案1】:

您需要转义特殊字符(${})。试试这个:

str.replaceAll("\\$\\{abc\\}","abc");

这可能很奇怪,但可以帮助您:

str = str.substring(str.indexOf("${")+2, str.indexOf("}"))

这适用于${} 之间的所有(任意数量)字符串。

【讨论】:

  • 我怎么知道它的abc。可以是“abcdef”
【解决方案2】:

我会在循环中反复使用String.indexOf(String sep, int start) 将文本和值复制到 StringBuilder。


类似

public static void main(String... args) throws IOException {
    Map<String, String> map = new LinkedHashMap<>();
    map.put("abc", "ABC");
    map.put("xyz", "XYZ");
    printSubstitue("nothing to change", map);
    printSubstitue("(&(objectclass=${abc})(uid=${xyz})(cn=${cn})(special='${'))", map);
}

private static void printSubstitue(String text, Map<String, String> map) {
    String text2 = subtitue(text, map);
    System.out.println("substitue( "+text+", "+map+" ) = "+text2);
}

public static String subtitue(String template, Map<String, String> map) {
    StringBuilder sb = new StringBuilder();
    int prev = 0;
    for (int start, end; (start = template.indexOf("${", prev)) > 0; prev = end + 1) {
        sb.append(template.substring(prev, start));
        end = template.indexOf('}', start + 2);
        if (end < 0) {
            prev = start;
            break;
        }
        String key = template.substring(start + 2, end);
        String value = map.get(key);
        if (value == null) {
            sb.append(template.substring(start, end + 1));
        } else {
            sb.append(value);
        }

    }
    sb.append(template.substring(prev));
    return sb.toString();
}

打印

substitue( nothing to change, {abc=ABC, xyz=XYZ} ) = nothing to change
substitue( (&(objectclass=${abc})(uid=${xyz})(cn=${cn})(special='${')), {abc=ABC, xyz=XYZ} ) 
     = (&(objectclass=ABC)(uid=XYZ)(cn=${cn})(special='${'))

如果你想支持嵌套的 ${ } 值,它会变得很混乱。 ;)

abc123=ghi123
abc${xyz}=def${xyz}

(&(objectclass=${abc${xyz}})(uid=${xyz}))

如果可以的话,我建议你保持简单。 ;)

【讨论】:

    【解决方案3】:

    您需要的正则表达式是\$\{[^}]+\}。替换为任何必要的内容。

    编辑:好的,我误解了这个问题。正则表达式已修复。

    【讨论】:

      【解决方案4】:

      这样的正则表达式有效:

      String regex = "(\\$\\{YOUR_TOKEN_HERE\\})";
      

      这是一个使用示例:

      public static void main(String[] args) throws Exception {
          String[] lines = {
              "(&(objectclass=${abc})(uid=${xyz}))",
              "(&(objectclass=${abc})(uid=${xyz})(xyz=${xyz})(abc=${abc}))"
          };
      
          String token = "abc"; // or whatever
      
          String regex = String.format("(\\$\\{%s\\})", token);
          Pattern p = Pattern.compile(regex);
          for (String s: lines) {
              Matcher m = p.matcher(s);
              if (m.find()) {
                  System.err.println(m.replaceAll("###"));
              }
          }
      }
      

      token = "abc" 的输出是:

      (&(objectclass=###)(uid=${xyz}))
      (&(objectclass=###)(uid=${xyz})(xyz=${xyz})(abc=###))
      

      【讨论】:

      • 谢谢。我怎么知道它的 abc 和 xyz?可以是 abcd 或 asdfgsdf
      猜你喜欢
      • 2019-09-03
      • 1970-01-01
      • 2013-06-25
      • 1970-01-01
      • 2016-01-08
      • 1970-01-01
      • 1970-01-01
      • 2012-03-14
      • 1970-01-01
      相关资源
      最近更新 更多