【问题标题】:How can I get a special part in a string in Java? [closed]如何在 Java 中获取字符串中的特殊部分? [关闭]
【发布时间】:2021-02-12 05:57:19
【问题描述】:

我必须从我拥有的文件中读取命令,并根据每个命令采取必要的措施。我能够找出从文件中读取的过程以及命令是什么,但是我无法将命令中包含的特定信息传输到程序中。例如,读取的行如下

Add id:12 name:"Sandik" singer:"Muslum Gurses" year:2009 count:5 price:20

如下所示,我已经在每个空间中分隔了这条阅读线。

 Scanner scan = new Scanner(new File(args[0]));
 while (scan.hasNextLine()) {
      String data = scan.nextLine();
      String[] readedCommand = data.split(" ");

在这个操作之后,readedCommands[0] 给了我读取命令。对于上面的例子,readedCommands[0] = "Add"

在这一步之后,我需要从命令的其余部分中提取信息,但我不知道如何提取诸如 id、name、singer 之类的信息。如果您能帮助我,我将不胜感激。提前谢谢你。

【问题讨论】:

标签: java regex string file split


【解决方案1】:

你可以通过将字符串拆分两次来做到这一点:

  1. 使用regex\s(?=\w+:)分割给定的字符串
  2. 然后从索引1 迭代生成的数组(因为索引处的字符串0 是命令)并在: 上进一步拆分每个元素

演示:

public class Main {
    public static void main(String[] args) {
        String data = "Add id:15 singer:\"Tarkan\" name:\"Adimi Kalbine Yaz\" year:2010 count:10 price:20";

        // First, split on whitespace
        String[] parts = data.split("\\s(?=\\w+:)");

        // The first element in the array is the command
        String command = parts[0];
        System.out.println("Command: " + command);

        // Split the remaining elements on ':'
        for (int i = 1; i < parts.length; i++) {
            String[] keyVal = parts[i].split(":");
            if (keyVal.length == 2) {
                String key = keyVal[0];
                String value = keyVal[1];
                System.out.println("Key: " + key + ", Value: " + value);
            }
        }
    }
}

输出:

Command: Add
Key: id, Value: 15
Key: singer, Value: "Tarkan"
Key: name, Value: "Adimi Kalbine Yaz"
Key: year, Value: 2010
Key: count, Value: 10
Key: price, Value: 20

正则表达式的解释,\s(?=\w+:):

  1. \s 指定空格。
  2. (?=\w+:)one or more 指定 positive lookahead word character(s) 后跟 :

【讨论】:

  • 感谢您的回答,但有问题。名字应该是 Sandik,歌手应该是 Muslum Gurses。不是“Sandik”和“Muslum”。我们该如何解决?
  • @Roxox - 我已经解决了这个问题。如有任何疑问/问题,请随时发表评论。
  • 你是最棒的家伙!
  • 这个代码的唯一问题是如果歌曲标题超过一个单词,它只需要第一个单词。对于这种情况:Add id:15 singer:"Tarkan" name:"Adimi Kalbine Yaz" year:2010 count:10 price:20 它的输出是:Command: Add Key: id, Value: 15 Key: singer, Value: "Tarkan" Key: name, Value: "Adimi Key: year, Value: 2010 Key: count, Value: 10 Key: price, Value: 20 我尝试对代码进行一些调整,但我几乎把它弄坏了。我想知道我们有什么办法可以处理这部分吗?
  • @Roxox - 让我检查一下。分析问题后我会在几分钟内更新答案。
【解决方案2】:

考虑以下代码。代码中的注释用于解释它的作用。

// Text block, first introduced as preview feature in JDK 13
String str = """
        Add id:12 name:"Sandik" singer:"Muslum Gurses" year:2009 count:5 price:20\
        """;
String[] parts = str.split(" ", 2);  // Create an array with no more than two elements.
System.out.println(Arrays.toString(parts));

// A single space that is not preceded by a quote mark followed by one or more word characters
// and also not succeeded by a string of one or more word characters followed by a quote.
String regex = "(?<!\"\\w+)\\s(?!\\w+\")";

// Splits on every space except for the space between 'Muslum' and 'Gurses'.
String[] list = parts[1].split(regex);
System.out.println(Arrays.toString(list));

// Used in the stream operation below.
// Split the string (elem) at the colon character and return the first array element.
Function<String, String> keyMapper = elem -> elem.split(":")[0];

// Used in the stream operation below.
Function<String, String> valueMapper = elem -> elem.split(":")[1];

Map<String, String> map = Arrays.stream(list)
                                .collect(Collectors.toMap(keyMapper, valueMapper));
System.out.println(map);

运行上面的代码会产生以下输出。

[添加,id:12 名称:“Sandik” 歌手:“Muslum Gurses” 年份:2009 计数:5 价格:20] [id:12,名称:“Sandik”,歌手:“Muslum Gurses”,年份:2009,数量:5,价格:20] {singer="Muslum Gurses", year=2009, price=20, name="Sandik", count=5, id=12}

【讨论】:

  • 仅供参考:我曾多次因仅通过代码中的 cmets 解释事情而没有在代码之外进行解释而受到处罚。以this 为例。和你一样,我认为这种解释方式没有问题,但群众有不同的看法。
【解决方案3】:

获得数组后,您可以通过split(":") 再次拆分每个字符串,以将键与值分开。使用HashMap 来存储键和值。

HashMap<String, String> hmap = new HashMap<String, String>();
 while (scan.hasNextLine()) {
      String data = scan.nextLine();
      String[] readedCommand = data.split(" ");
      for(int i = 1; i < readedCommand.length; i++){
          String[] pair = readedCommand[i].split(";");
          hmap.put(pair[0], pair[1]);
      }

}

【讨论】:

  • 对空格字符进行拆分可能会错误地破坏字符串值。
  • 感谢您的回答,但我仍然不知道如何访问此处的信息。我尝试打印 pair [0] 之类的东西,但它没有用。这里的分割信息保存在哪里?
  • 简而言之,我会把从这里拉出来的id、name、singer……等信息发送到一个链表中。为此,我需要分配此信息的变量。这些变量到底是什么?
  • 而且当我像你展示的那样更新我的代码时,我试图运行它,但它在线程“main”java.lang.ArrayIndexOutOfBoundsException 中给了我异常:索引 1 超出长度 1 的范围Main.main(Main.java:38)
猜你喜欢
  • 1970-01-01
  • 2016-04-03
  • 2019-12-13
  • 1970-01-01
  • 1970-01-01
  • 2016-10-01
  • 1970-01-01
  • 2021-03-03
  • 1970-01-01
相关资源
最近更新 更多