在字符串中查找特殊的数字序列(坐标)

Finding a special sequence of numbers (coordinates) in a string

我们的项目中有两种坐标。 正常的 x, y 和 z

示例:

101, 520, 62
960.93 764.22 59.20

以及具有 6 位数字的扩展版本(2x xyz 用于位置和旋转) 示例:

101 520 62 3 0 0
960.93 764.22 59.20 -0.34 0.00 -89.81

它们可以是负数,可以是浮点数,也可以是四舍五入的数字。 它们可以用逗号分隔,也可以什么都不分隔

使用 python,我试图在字符串中找到任何坐标。

示例:

textbefore 101, 520, 62
GOTO 960.93 796.22 59.20 -0.34 0.00 -89.81
GOTO 1960.93 1796.22 159.20 -0.34 0.00 -89.81
501, 513, 162
1040, 1040, 520 text after 
error
222, 222
1500, 1500, 60  (1)
1337 1337 65
124.5, 133.6, 35.4
15:13:26  Condition: index_ != StringList::npos [line 178](125, 157, 215) 
Allocating shadow map cache 6324 x 6324: 76.28 MB

在完美世界中输出应该是:

101 520 62
960.93 796.22 59.20 -0.34 0.00 -89.81
1960.93 1796.22 159.20 -0.34 0.00 -89.81
501 513 162
1040 1040 520
1500 1500 60
1337 1337 65
124.5 133.6 35.4
125 157 215 

最后一行“分配阴影贴图,有点棘手,如果失败并被列为坐标,那很好。

我在这里使用了这段代码,它很好地过滤了数字,然后我检查了 6 或 3 个数字,但我遇到了数字更多的行的问题。 所以我需要某种逻辑来检查数字是否彼此“接近”甚至被单词分隔。

re.findall("[-+]?[.]?[\d]+(?:,\d\d\d)*[\.]?\d*(?:[eE][-+]?\d+)?", line)

如果可能的话,代码应该可以在 Python 2.7 上运行(遗憾的是我们远远落后)。

谢谢

在深入研究代码之前,您需要找出伪代码中的算法或方法来执行您的要求。 在此示例中,您需要创建 python 代码来识别数字:

def is_number(input):
    if type(input) == int or type(input) == float:
        return True
    else:
        return False

然后我将按空格或逗号拆分并解析您创建的数组以查找连续的 3 或 6 个真值

s = '''textbefore 101, 520, 62
GOTO 960.93 796.22 59.20 -0.34 0.00 -89.81
GOTO 1960.93 1796.22 159.20 -0.34 0.00 -89.81
501, 513, 162
1040, 1040, 520 text after 
error
222, 222
1500, 1500, 60  (1)
1337 1337 65
124.5, 133.6, 35.4
15:13:26  Condition: index_ != StringList::npos [line 178](125, 157, 215) 
Allocating shadow map cache 6324 x 6324: 76.28 MB'''
s = s.split('\n')
s_row = []
for i in range(len(s)):
    s_row.append(s[i].replace(',', '').split(' '))

coord = []
for i in range(len(s_row)):
    coord_row = []
    for j in range(len(s_row[i])):
        try:
            s_row[i][j] = float(s_row[i][j])
            coord_row.append(s_row[i][j])
        except ValueError:
            None
    if coord_row != []:
        coord.append(coord_row)

将为您提供以下输出:


[[101.0, 520.0, 62.0]
[960.93, 796.22, 59.2, -0.34, 0.0, -89.81]
[1960.93, 1796.22, 159.2, -0.34, 0.0, -89.81]
[501.0, 513.0, 162.0]
[1040.0, 1040.0, 520.0]
[222.0, 222.0]
[1500.0, 1500.0, 60.0]
[1337.0, 1337.0, 65.0]
[124.5, 133.6, 35.4]
[157.0]
[6324.0, 76.28]]

您可以使用正则表达式来做到这一点。由于 python 附带的 re 模块不能很好地处理重复或嵌套的捕获组,您最好从部分组装一个更大的正则表达式。

r"([-+]?[\d+][\.\d]*)"

是一个正则表达式,它将匹配带有可选符号的小数或浮点数。 [-+]? 匹配符号,[\d+] 匹配点前至少一位小数,[\.\d]* 匹配浮点数的可选小数部分,外部 () 告诉正则表达式发出捕获的字符串。

r"[ ,]*"

是decimal/floats之间的分隔符。现在你可以一起写出其中的 3 和 6 个,但是下面的代码用一点 python.

来做到这一点
import re
import io

test = io.StringIO("""textbefore 101, 520, 62
GOTO 960.93 796.22 59.20 -0.34 0.00 -89.81
GOTO 1960.93 1796.22 159.20 -0.34 0.00 -89.81
501, 513, 162
1040, 1040, 520 text after 
error
222, 222
1500, 1500, 60  (1)
1337 1337 65
124.5, 133.6, 35.4
15:13:26  Condition: index_ != StringList::npos [line 178](125, 157, 215) 
Allocating shadow map cache 6324 x 6324: 76.28 MB""")


# assemble regex from matching 1 decimal or float coord into 3 or 6
_one = r"([-+]?[\d+][\.\d]*)"
_sep = "[ ,]+"
coord_3 = re.compile(_sep.join([_one]*3))
coord_6 = re.compile(_sep.join([_one]*6))

coords = []
for line in test:
    match = coord_6.search(line) or coord_3.search(line)
    if match is not None:
        print(match.groups())
        coords.append(" ".join(match.groups()))

for c in coords:
    print(c)

您可以为此使用以下正则表达式

(?:(?:[+-]?\d+\.?\d*[ ,]+){5}[+-]?\d+\.?\d*)|(?:(?:[+-]?\d+\.?\d*[ ,]+){2}[+-]?\d+\.?\d*)

这将搜索以 ,space 分隔的 2/5 个连续数字和具有非数字值的第 3/6 个数字。

Here 是一个演示。

输出

['101, 520, 62',
 '960.93 796.22 59.20 -0.34 0.00 -89.81',
 '1960.93 1796.22 159.20 -0.34 0.00 -89.81',
 '501, 513, 162',
 '1040, 1040, 520',
 '1500, 1500, 60',
 '1337 1337 65',
 '124.5, 133.6, 35.4',
 '125, 157, 215']