我是新手使用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.
我正在考虑为每个值创建组,因为这样我就可以通过组合Pattern
和Matcher
类来轻松创建数组,因此:
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();
}
}
}