在字符串中查找特殊的数字序列(坐标)
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']
我们的项目中有两种坐标。 正常的 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']