我正在寻找一个正则表达式来识别可能是具有相同长度的列的二维整数数组的字符串。
例如,这是一个我想将其转换为二维数组的字符串:
0 4 8 4\n9 6 5 7\n9 5 5 1
可能是:
0 4 8 4
9 6 5 7
9 5 5 1
所以我想出了这个:"(([0-9]+[ \t]?)+(\n|\r)?){1,}"
但是它没有检查列是否具有相同的长度。
谢谢你的帮助。
答案 0 :(得分:2)
如果您想直接regex
验证二维数组,可以构建验证特定“x by y”二维数组的模式。
public static void main(String[] args) throws Exception {
String data = "0 4 8 4\n9 6 5 7\n9 5 5 1";
// Check if the data is either a 2 x 2 - 10 x 10 array
for (int row = 2; row <= 10; row++) {
for (int col = 2; col <= 10; col++) {
Matcher matcher = Pattern.compile(buildPattern(row, col)).matcher(data);
if (matcher.matches()) {
System.out.printf("Valid %d x %d array%n", row, col);
return;
}
}
}
System.out.println("Invalid 2d array");
}
public static String buildPattern(int row, int col) {
StringBuilder patternBuilder = new StringBuilder();
for (int r = 0; r < row; r++) {
for (int c = 0; c < col; c++) {
patternBuilder.append("\\d+");
if (c + 1 < col) patternBuilder.append("[ ]");
}
if (r + 1 < row) patternBuilder.append("\n");
}
return patternBuilder.toString();
}
结果:
Valid 3 x 4 array
我会做2次分裂。
从那里,我将获得与第一行具有相同列数的行数。如果结果等于split 1中的行数,那么我们就知道它是一个二维数组。否则,它是一个锯齿状阵列。
public static void main(String[] args) throws Exception {
String data = "0 4 8 4\n9 6 5 7\n9 5 5 1";
// Get the rows
String[] rows = data.split("[\r]?[\n]");
// Get the number of columns in the first row
int colCount = rows[0].split(" ").length;
// Check if all rows have the same number of columns as the first row
if (Arrays.stream(rows)
.filter(row -> row.split(" ").length == colCount)
.count() == rows.length) {
System.out.println("Valid 2d array");
} else {
System.out.println("Jagged array");
}
}
结果:
Valid 2d array
答案 1 :(得分:2)
您可以使用这种模式(如果需要,添加可选的CR):
(?m)^(?>(?>\\d+([ \\t]|$)(?=.*\\n(\\2?+\\d+\\1)))+\\n(?=\\2$))+.*
demo (点击java按钮)
对于第一行中的每个项目,前瞻检查下一行中是否存在同一列中的项目。要知道列是否相同,捕获组2包含可选的自引用\\2?+
。这样,每当“项目”组重复(并到达下一列)时,捕获组2就会增长。
细节:
(?m) # use the multiline mode
^ # start of the line
(?> # group for a complete line
(?> # group for an item
\\d+ ([ \\t]|$) # a number followed by a space/tab or the end of the line
(?= # looakead
.*\\n # reach the next line
(\\2?+\\d+\\1) # capture group 2
)
)+ # repeat the item group
\\n
(?=\\2$) # check if there isn't more columns in the next line
)+ # repeat the line group
.* # match the next line
注意:此模式检查分隔符是否唯一(不重复),并且始终与([ \\t]|$)
和\\1
相同(在捕获组2中)。不允许使用前导和尾随空格。但是你可以用更灵活的方式编写它:
(?m)^(?>[ \\t]*(?>\\d+[ \\t]*(?=.*\\r?\\n(\\1?+\\d+(?:[ \\t]+|[ \\t]*$))))+\\r?\\n(?=\\1$))+.*\\2$))+.*
这些模式既可以用matches()
来检查整个字符串,也可以用find()
来查找更大字符串中的最终数组。