正则表达式重新格式化整数块(魔术方块)

时间:2015-07-25 21:05:37

标签: regex

正则表达式要求

我有一个包含魔术方块的大文件,以四个为一组,以空格分隔:

 2 16  1 15    10  5 12  7     9  3 14  8    13  6 11  4
14  9  8  3     3  9  8 14     5 10  7 12    12 10  7  5
11  4 13  6     6  4 13 11    16 15  2  1     1 15  2 16
 7  5 12 10    15 16  1  2     4  6 11 13     8  3 14  9

最终我想找到并重新格式化这些组,以便每个单独的魔术方块分别出现如下:

 2 16  1 15
14  9  8  3
11  4 13  6
 7  5 12 10

10  5 12  7
 3  9  8 14
 6  4 13 11
15 16  1  2

 9  3 14  8
 5 10  7 12
16 15  2  1
 4  6 11 13

13  6 11  4
12 10  7  5
 1 15  2 16
 8  3 14  9

查找每组四位数

首先,我有一个Regex找到所有四个数字的组,但这只给了我需要的16个匹配如果我指定每个前面有0-2个空格的整数:

(( {0,2}\d{1,2}){4}).*?

saved version on Regexr

解决方案的问题

我想在每列的开头只捕获整数前面的零或一个空格,但是将每个16的每个块分开的四个。

更大的问题

然后我需要捕获16个四个整数组中的每一个并将其重新格式化为捕获的组

\1\5\9\13\n\n

给予:

 2 16  1 15
14  9  8  3
11  4 13  6
 7  5 12 10

但到目前为止我的正则表达式捕获了一切。如何分离捕获组以实现此目的?

3 个答案:

答案 0 :(得分:2)

我可以建议你这样的事情:

(( {0,2}?\d{1,2}){4}) +(( {0,2}?\d{1,2}){4}) +(( {0,2}?\d{1,2}){4}) +(( {0,2}?\d{1,2}){4})

你可以得到这样的结果:

$1

 2 16  1 15
14  9  8  3
11  4 13  6
 7  5 12 10

$3

10  5 12  7
3  9  8 14
6  4 13 11
15 16  1  2

$5
...

$7
...

答案 1 :(得分:2)

似乎正则表达式不是这项工作的好选择,但它是可能的。要同时匹配所有四个方块,并按照你想要的顺序提取它们,你可以使用这个荒谬的长正则表达式:

^((?:\s{0,2}\d+)+)\s+((?:\s{0,2}\d+)+)\s+((?:\s{0,2}\d+)+)\s+(.+)\n((?:\s{0,2}\d+)+)\s+((?:\s{0,2}\d+)+)\s+((?:\s{0,2}\d+)+)\s+(.+)\n((?:\s{0,2}\d+)+)\s+((?:\s{0,2}\d+)+)\s+((?:\s{0,2}\d+)+)\s+(.+)\n\s+((?:\s{0,2}\d+)+)\s+((?:\s{0,2}\d+)+)\s+((?:\s{0,2}\d+)+)\s+((?:\s{0,2}\d+)+)

DEMO

然后使用$ 1到$ 16之间的所有组来获得正方形。但是我不确定它是否比正则表达式练习更有用。

答案 2 :(得分:2)

使用像python

这样的脚本语言

这是我的解决方案。我认为工作得很好。

squares = []
row_counter = 0
four = None
with open('magic-squares.txt') as f:
    for row in f:
        numbers = row.split()
        if numbers:
            if row_counter == 0:
                if four:
                    squares += four
                four = [[],[],[],[]]
            for i in range(4):
                four[i] += numbers[i*4:i*4+4]
            row_counter += 1
            row_counter %= 4

with open('output.txt', 'w') as f:
    f.write('\n'.join(' '.join(square) for square in squares))

with open('output2.txt', 'w') as f:
    f.write(
        '\n\n'.join(
            '\n'.join(
                ''.join(
                    ["{:<2} ".format(item) for item in square[i*4:(i+1)*4]]
                ) for i in range(4)
            ) for square in squares
        )
    )