【问题标题】:Extract from formatted string using Java使用 Java 从格式化字符串中提取
【发布时间】:2015-01-25 01:16:14
【问题描述】:

我有以下格式的字符串:

  • [(xx)(KEY1)一些文字]
  • 一些文字[(yy)(KEY1)一些文字]
  • 一些文字 [(qq)(KEY1)some text] 更多文字在这里 [(zz)(KEY2)some text] 等等。

基本上 [(xx)(KEYX)some text] 形式在与其他字符混合的字符串中出现一次或多次。

上述格式中,key为KEYX,value为some text

我想从包含任意数量的此类格式的任何字符串中提取所有键值对。

我尝试使用子字符串等进行直接解析,但这似乎不是一个干净的解决方案。使用正则表达式或 Java 提供的任何其他技术是否可以做得更好?

【问题讨论】:

  • KEYX 总是 4 个字符吗?它总是以第三个字符开头吗?
  • KEYX 是一个可变字符串。它可以采用任何字符串值。但它总是包含在 () 中。它始终是第三个字符。前缀值 (xx) 或 (yy) 完全一样。

标签: java regex string parsing


【解决方案1】:

您可以使用正则表达式和匹配器来查找您的键和值:

     public static void main(String[] args) throws IOException
     {
         String test = "[(xx)(KEYX)some text]";
         Pattern pattern = Pattern.compile("\\(KEY.*\\)");

         Matcher matcher = pattern.matcher(test);
         matcher.find();
         String s = matcher.group(0);
         String s1 = test.substring(matcher.end(), test.length() - 1);
         System.out.println("" + s + "   " + s1);

     }

这个输出是:

(KEYX)   some text

如果您将字符串更改为"[(xx)(KEYXYYYYYY)some text]",那么它将是:

(KEYXYYYYYY)   some text

如果您不想在键周围加上括号:

 public static void main(String[] args) throws IOException
 {
     String test = "[(xx)(KEYXYYYYYY)some text]";
     Pattern pattern = Pattern.compile("(?<=\\()KEY.*(?=\\))");

     Matcher matcher = pattern.matcher(test);
     matcher.find();
     String s = matcher.group(0);
     String s1 = test.substring(matcher.end() + 1, test.length() - 1);
     System.out.println("" + s + "   " + s1);

 }

输出将是:

KEYXYYYYYY   some text

**************************************************** ***************更新********************************** ************************ 匹配任何键,而不仅仅是 KEY:

 public static void main(String[] args) throws IOException
 {
     String test = "[(xx)(time.zone1)some text]";
     Pattern pattern = Pattern.compile("(?<=\\()[^xy].*(?=\\))");

     Matcher matcher = pattern.matcher(test);
     matcher.find();
     String s = matcher.group(0);
     String s1 = test.substring(matcher.end() + 1, test.length() - 1);
     System.out.println("" + s + "   " + s1);

 }

这将输出:

time.zone1   some text

**************************************************** ***********更新************************************** ********

同一字符串中的多个匹配项:

 public static void main(String[] args) throws IOException
 {
     String test = "[(xx)(time1.zone1)some text1]blahblahblah[(xx)(time2.zone2)some text2]";
     Pattern pattern = Pattern.compile("(?<=\\()[^xy].*?]");

     Matcher matcher = pattern.matcher(test);
     while(matcher.find())
     {
         String s = matcher.group(0);
         String s1 = s.substring((s.indexOf(")") + 1), (s.length() - 1));
         s = s.substring(0, s.indexOf(")"));
         System.out.println("" + s + "   " + s1);
     }

 }

这将输出:

time1.zone1   some text1
time2.zone2   some text2

【讨论】:

  • 谢谢brso5。不过有一件事。密钥不以字符串“KEY”开头。它可以是任何东西。例如,以下都是有效的键:time.zone1; url.someval; some.key.val 等
  • @naspras 嘿,伙计,我刚刚更新了它,所以你可以匹配任何键,而不仅仅是以 KEY 开头的东西...查看更新部分
  • 我最近几天不在。这个解决方案对我所需要的很有帮助。谢谢!
  • 如果我有这样的输入,它不起作用:一些文本 [(XX)(A.KEY)some_text] 写等等等等 [(XX)(OTHER.VAL)some_more_text] 你好。简单的目的是在每次出现 (XX) 之后查找键 (A.KEY, OTHER.VAL)。
  • 所以你的意思是所有在一个字符串?您应该使用匹配器的循环...我可以为此发布代码。
【解决方案2】:

如果我理解您的问题,您可以依靠 KEY 从第四个字符开始,然后找到下一个“)”,例如

String str = "(xx)(KEY1)some text";
int open = str.indexOf("(", 4);
int pos = str.indexOf(")", 4);
str = str.substring(open + 1, pos);
System.out.println(str);

输出是

KEY1

【讨论】:

    猜你喜欢
    • 2016-10-15
    • 2021-12-07
    • 1970-01-01
    • 1970-01-01
    • 2021-08-03
    • 2023-01-07
    • 2017-12-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多