Java正则表达式:从字符串中提取信息到变量

3

我正在使用Java中的正则表达式提取字符串的三个部分,以下是工作代码。我对正则表达式相对较新,感觉使用多个表达式来进行如此简单的搜索和提取有点愚蠢。

你们中的任何人能否帮助我找到更优雅和简单的解决方案?我需要将数据存储在三个分离的变量中,如代码所示。

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Test {

    public static void main(String[] args) {

        String input = "lat: 56.894205 long: 008.528896 speed: 000.0 24/02/13 21:21   bat:F signal:F  imei:12345678901";

        String lat = regexSearch("(?<=lat: )\\d+.\\d+", input);
        String lng = regexSearch("(?<=long: )\\d+.\\d+", input);
        String imei = regexSearch("(?<=imei:)\\d+", input);

        if (lat != null && lng != null && imei != null) {
            System.out.println(lat);
            System.out.println(lng);
            System.out.println(imei);
        }
    }

    public static String regexSearch(String regex, String input) {
        Matcher m = Pattern.compile(regex).matcher(input);
        if (m.find()) return m.group();
        return null;
    }

}

输出:

56.894205
008.528896
12345678901

编辑: 我需要处理“lat”和“long”数据长度的代码(例如56.89405和56.894059等)。


2
这个问题更适合提问在代码审查上。 - Mena
如果是我,我会使用substring、indexOf("lat: ")等方法来避免使用三个编译好的正则表达式。 - Smutje
字符串的格式会一直保持不变吗? - TheLostMind
@TheLostMind:正如我的编辑所示,该字符串的长度将会不同,例如纬度和经度信息中可能包含更多数字。 - user2543930
@SimonGregersen - 如果字符串的格式/模式将保持不变,那么您可以看一下我的解决方案。 - TheLostMind
3个回答

4
你可以使用命名捕获组来分离匹配组,然后将每个匹配组分配给你选择的字符串变量。以下是一个可供参考的工作示例...
String s  = "lat: 56.894205 long: 008.528896 speed: 000.0 24/02/13 21:21   bat:F signal:F  imei:12345678901";
Pattern p = Pattern.compile("lat: (?<lat>\\d+\\.\\d+) long: (?<lng>\\d+\\.\\d+).*imei:(?<imei>\\d+)");
Matcher m = p.matcher(s);
while (m.find()) {
    String lat  = m.group("lat");
    String lng  = m.group("lng");
    String imei = m.group("imei");
    System.out.println(lat);  //=> "56.894205"
    System.out.println(lng);  //=> "008.528896"
    System.out.println(imei); //=> "12345678901"
}

1
非常感谢 - 那个解决方案解决了我的问题! - user2543930

1
您可以像这样简化代码:

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Test {

    public static void main(String[] args) {

        String input = "lat: 56.894205 long: 008.528896 speed: 000.0 24/02/13 21:21   bat:F signal:F  imei:12345678901";

        Pattern p = Pattern.compile("lat:\\s+(?<latitude>\\d+\\.\\d+)\\s+long:\\s+(?<longitude>\\d+\\.\\d+)\\s+.+?imei:(?<imei>\\d+)");
        Matcher m = p.matcher(input);

        if (m.find()) {
            String lat = m.group("latitude");
            String lng = m.group("longitude");
            String imei = m.group("imei");

            System.out.println(lat);
            System.out.println(lng);
            System.out.println(imei);
        }
    }
}
  • 我只使用一个正则表达式来提取数字。编译模式可能会很耗费时间。
  • 我使用了带名称的捕获组 ((?<latitude>...)。它使得正则表达式更容易阅读。
  • 捕获组捕获的值可以通过Matcher#group(String name)获取。

1
非常感谢您的解决方案!太棒了! - user2543930

0
术语“优雅”是相对的,因人而异。所以,从我的角度来看,你可以使用一个单一的正则表达式,就像这样:
public static void main(String[] args) {
    String input = "lat: 56.894205 long: 008.528896 speed: 000.0 24/02/13 21:21   bat:F signal:F  imei:12345678901";
    Pattern p = Pattern.compile("(\\d+\\.\\d+)(?!\\s\\d+)|(\\d+$)"); // negative lookahead to prevent matching of speed
    Matcher m = p.matcher(input);
    while (m.find()) {
        System.out.println(m.group());
    }

}

输出:

56.894205
008.528896
12345678901

我该如何将信息提取到单独的变量中呢? - user2543930
1
@SimonGregersen - 你可以将它们添加到一个列表中,然后从列表中获取值。在位置0处,你会得到纬度,在位置1处你会得到经度,在位置2处你会得到IMEI号码。 - TheLostMind
@AvinashRaj - 那么这个答案就不适用了。他可以使用他的正则表达式或其他东西。他实际上可能会使用split。 - TheLostMind

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接