复杂字符串的正则态度



我是新手使用Regex的新手,并试图将其与Java引擎一起使用。我要分析的示例字符串如下:

name:"SFATG";affil:100;aup:1;bu:FALSE name:"SF TAC 1";affil:29.3478;aup:19;bu:FALSE name:"SF TAC 2";affil:22.2222;aup:14;bu:FALSE name:"SF TAC 3";affil:44.4444;aup:0;bu:FALSE name:"SF DISP 4";affil:82.4742;aup:0;bu:FALSE 

我希望将正则态度达到的是仅提取:之后和;之前出现的值。此外,我不想在name的条目中包括引号。但是,我(在这种非常特殊的情况下)喜欢保留出现在bu条目中的空间。但是,我不会希望出现name字段以用于bu的数据输入。所以我想要FALSE,而不是此字段的FALSE name

我使用此正格的最终目标是创建来自所有组/数据值的数组,以便数组包含以下内容:

[0]: SFATG
[1]: 100
[2]: 1
[3]: FALSE 
[4]: SF TAC 1
...Etc.

我正在考虑为每个值创建组,因为这样我就可以通过组合PatternMatcher类来轻松创建数组,因此:

String regEx = "Some really fancy RegEx that actually works";
Pattern p = Pattern.compile(regEx);
Matcher m = p.matcher("Some really really long String that follows the outlined format");
// I'd probably want to use an Object array since my data values vary by type
// I can also create 4 different arrays (one for name, another for affil, etc.),
// Any advice on which approach to take?
Object[] dataValues = new Object[m.groupCount()];

我迄今为止能够提出的正则是如下:

name:"(w+)";affil:(d+);aup:(d+);bu:(w+s)

但是,这似乎仅适用于前4个数据值,而没有其他功能。

有人可以帮助我创建与我正在合作的数据的正则表达式吗?对此的任何帮助将不胜感激!我还对其他如何处理此操作的想法开放,例如使用不同的数据类型以后存储数据(创建对象数组除外)。关键是以某种方式从我提到的字符串中获取数据值,并存储它们以进行处理。

其他问题我想可能有外部库可能更适合执行此任务。有人知道可以为此工作的库吗?

一条正则统治它们

w+:(?:"([^"]+)"|(d+)(?=;|Z)|(d+.d+)|([A-Z]+s))

请参阅 REGEX101.com上的演示


分解,这说:

w+:                 # 1+ word characters, followed by :
(?:                  # a non-capturing group
    "([^"]+)"        # "(...)"
    |                # or
    (d+)(?=;|Z)    # only digits (no floats)
    |                # or
    (d+.d+)       # floats
    |                # or
    ([A-Z]+s)       # only UPPERCASE, followed by space
)

在这里,您需要查看填充哪个捕获组,此外,在Java中需要两个后斜线(即\d+而不是d+)。要检查哪个组匹配,您需要一些编程逻辑,例如 https://ideone.com/sbgzxy (我不是Java家伙)。

虽然此言论的通用性不如 @jan的答案,但它确实限制了数据中的字段,因此它将提供语法检查:

name:"([^"]+)";affil:([d.]+);aup:(d+);bu:(TRUE|FALSE) ?

关于提取值的方法,我会创建一个薄包装器对象来提供类型安全:

public class RowParser {
    private static final Pattern ROW_PATTERN = Pattern.compile("name:"([^"]+)";affil:([\d.]+);aup:(\d+);bu:(TRUE|FALSE) ?");
    public static void main(String[] args) {
        String data = "name:"SFATG";affil:100;aup:1;bu:FALSE name:"SF TAC 1";affil:29.3478;aup:19;bu:FALSE name:"SF TAC 2";affil:22.2222;aup:14;bu:FALSE name:"SF TAC 3";affil:44.4444;aup:0;bu:FALSE name:"SF DISP 4";affil:82.4742;aup:0;bu:TRUE n";
        System.out.println(parseRows(data));
    }
    public static List<Row> parseRows(String data) {
        Matcher matcher = ROW_PATTERN.matcher(data);
        List<Row> rows = new ArrayList<>();
        while (matcher.find()) {
            rows.add(new Row(matcher));
        }
        return rows;
    }
    // Wrapper object for individual data rows
    public static class Row {
        private String name;
        private double affil;
        private int aup;
        private boolean bu;
        Row(Matcher matcher) {
            this.name = matcher.group(1);
            this.affil = Double.parseDouble(matcher.group(2));
            this.aup = Integer.parseInt(matcher.group(3));
            this.bu = Boolean.parseBoolean(matcher.group(4));
        }
        public String getName() {
            return name;
        }
        public double getAffil() {
            return affil;
        }
        public int getAup() {
            return aup;
        }
        public boolean isBu() {
            return bu;
        }
        @Override
        public String toString() {
            return "name:"" + name + '"' + ";affil:" + affil + ";aup:" + aup + ";bu:" + String.valueOf(bu).toUpperCase();
        }
    }
}

最新更新