【问题标题】:Finding a special sequence of numbers (coordinates) in a string在字符串中查找特殊的数字序列(坐标)
【发布时间】:2021-09-01 15:01:55
【问题描述】:

我们的项目中有两种坐标。 带 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
$5GOTO 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 python-2.7 coordinates python-re


【解决方案1】:

您可以使用下面的正则表达式

(?:(?:[+-]?\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']

【讨论】:

  • 太棒了,谢谢。另外我不知道正则表达式编辑器,这真的很有帮助。
【解决方案2】:

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

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

然后我会拆分空格或逗号并解析您创建的数组,以连续查找 3 或 6 个 True

【讨论】:

  • 请添加更多详细信息以扩展您的答案,例如工作代码或文档引用。
【解决方案3】:
s = '''textbefore 101, 520, 62
GOTO 960.93 796.22 59.20 -0.34 0.00 -89.81
$5GOTO 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]]

【讨论】:

    【解决方案4】:

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

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

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

    r"[ ,]*"
    

    是小数/浮点数之间的分隔符。现在你可以把这些东西中的 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
    $5GOTO 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)
    

    【讨论】:

      猜你喜欢
      • 2023-03-24
      • 1970-01-01
      • 1970-01-01
      • 2012-06-18
      • 1970-01-01
      • 2021-08-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多