如何用正则关联不同行的Point名称与对应4x4变换矩阵
Got it, let's solve this problem cleanly. The challenge is linking each PointN name to its 4x4 transform matrix, even though they're on separate lines. Instead of running two separate matches and hoping they align, we can write a single regex pattern that captures both pieces of data in one go, using Python's regex flags to handle multi-line content.
The Regex Pattern
We'll use a pattern that first targets the Point name, then skips any intervening content (including newlines) to capture the 16 floating-point values of the transform matrix. Here's the pattern, formatted for readability:
import re pattern = r""" name 'Point(\d+)' # Capture the unique number for each Point .*? # Non-greedy match any characters (including newlines) until... transform # We hit the transform keyword for this Point (?:\s+([-+]?\d+\.\d+e[+-]?\d+)){16} # Capture all 16 scientific notation floats for the 4x4 matrix """
We'll pair this with two key regex flags:
re.DOTALL: Makes the.character match newlines, so our.*?can span lines between the Point name and its transform data.re.VERBOSE: Lets us add comments and whitespace to the regex for clarity (you can omit this if you condense the pattern into a single line).
Python Implementation Example
Here's how to apply this to your sample text and turn the matches into structured data ready for 3D processing:
import re import numpy as np # Your input text from the example input_text = """scenegraph { name 'Root' visible 1 transform 1.000000000e+00 0.000000000e+00 0.000000000e+00 0.000000000e+00 0.000000000e+00 1.000000000e+00 0.000000000e+00 0.000000000e+00 0.000000000e+00 0.000000000e+00 1.000000000e+00 0.000000000e+00 0.000000000e+00 0.000000000e+00 0.000000000e+00 1.000000000e+00 geometry 0 children 2 [ scenegraph { name 'Point1' visible 1 transform 8.133591413e-01 0.000000000e+00 0.000000000e+00 0.000000000e+00 0.000000000e+00 8.133591413e-01 0.000000000e+00 0.000000000e+00 0.000000000e+00 0.000000000e+00 8.133591413e-01 0.000000000e+00 9.277027100e-02 6.371318848e+03 4.141105652e+02 1.000000000e+00 geometry { vertices 1 4294967295 0 edges 0 faces 0 vertex_attrs 2 [ attribute { name 'align_2d' type 'vec2' startTime 1.03900000000000000e+03 initialVals 1 [ - ] keys 2 [ 1.03900000000000000e+03 0 1.408942139e+03 7.712362671e+02 1.08900000000000000e+03 0 8.704575806e+02 9.245101929e+02 ] } attribute { name 'pts_3d' type 'vec3' startTime 0.00000000000000000e+00 initialVals 1 [ + 0.000000000e+00 0.000000000e+00 0.000000000e+00 ] keys 0 [ ] } ] edge_attrs 0 [ ] face_attrs 0 [ ] selected 1 } children 0 [ ] } scenegraph { name 'Point2' visible 1 transform 3.526667595e+00 0.000000000e+00 0.000000000e+00 0.000000000e+00 0.000000000e+00 3.526667595e+00 0.000000000e+00 0.000000000e+00 0.000000000e+00 0.000000000e+00 3.526667595e+00 0.000000000e+00 -4.233531475e+00 6.362593262e+03 4.306122437e+02 1.000000000e+00 geometry { vertices 1 4294967295 0 edges 0 faces 0 vertex_attrs 2 [ attribute { name 'align_2d' type 'vec2' startTime 1.04500000000000000e+03 initialVals 1 [ - ] keys 2 [ 1.04500000000000000e+03 0 4.777643433e+02 1.594472809e+02 1.05300000000000000e+03 0 1.969290161e+02 -1.577421112e+02 ] } """ # Compile the regex with flags regex = re.compile(pattern, re.DOTALL | re.VERBOSE) # Find all matching Point-transform pairs matches = regex.findall(input_text) # Convert matches into a usable dictionary with 4x4 matrices point_transforms = {} for match in matches: point_id = match[0] # Extract and convert the 16 matrix values to floats matrix_values = [float(val) for val in match[1:]] # Reshape into a 4x4 numpy array for easy 3D processing point_transforms[f"Point{point_id}"] = np.array(matrix_values).reshape(4, 4) # Example output to verify for point_name, matrix in point_transforms.items(): print(f"\n{point_name} Transform Matrix:") print(matrix)
Why This Works
- Non-greedy
.*?: Ensures we only capture content between the current Point's name and its own transform, avoiding accidental jumps to the next Point's data. re.DOTALL: Essential for handling the multi-line content that separates the Point name from its transform values.- Capturing Groups: The first group grabs the Point's unique number, and the repeated group captures each of the 16 matrix values directly.
- Structured Output: We map each Point name to a 4x4 numpy array, which is ideal for further spatial calculations in Python.
This method is far more reliable than separate matches because it directly links each Point to its transform in a single regex pass, eliminating alignment errors entirely.
内容的提问来源于stack exchange,提问作者J. doe

