pythonregexmapping

How do I match numbers from protocol messages to mapping groups?


I have protocol messages from a device:

560-1X490-3
238-3X458-7
667-9X560-1
170-8X233-8
570-2X155-1

I also have a mapping table:

mapping = {
    0: [127,136,145,190,235,280,370,389,460,479,569,578,118,226,244,299,334,488,668,677,0,550],
    1: [128,137,146,236,245,290,380,470,489,560,678,579,119,155,227,335,344,399,588,669,100,777],
    2: [129,138,147,156,237,246,345,390,480,570,679,589,110,228,255,336,499,660,688,778,200,444],
    3: [120,139,148,157,238,247,256,346,490,580,670,689,166,229,337,355,445,599,779,788,300,111],
    4: [130,149,158,167,239,248,257,347,356,590,680,789,112,220,266,338,446,455,699,770,400,888],
    5: [140,159,168,230,249,258,267,348,357,456,690,780,113,122,177,339,366,447,799,770,500,555],
    6: [123,150,169,178,240,259,268,349,358,457,367,790,114,277,330,448,466,556,880,899,600,222],
    7: [124,160,179,250,269,278,340,359,368,458,467,890,115,133,188,223,377,449,557,566,700,999],
    8: [125,134,170,189,260,279,350,369,378,459,567,468,116,224,233,288,440,477,558,990,800,666],
    9: [126,135,180,234,270,289,360,379,450,469,117,478,568,144,199,225,388,559,577,667,900,333],
}

For each number in the message I want to print which mapping group (0-9) it belongs to, or None if not found:

Message: 560-1X490-3.

  560 -> group 1.
  1   -> group None.
  490 -> group 3.
  3   -> group None.
import re

def check_mapping(val, mapping):
    for group, vals in mapping.items():
        if val in vals:
            return group
    return None

messages = [
    "560-1X490-3",
    "238-3X458-7",
    # ...
]

for msg in messages:
    nums = list(map(int, re.findall(r'\d+', msg)))
    print(f"Message: {msg}")
    for n in nums:
        group = check_mapping(n, mapping)
        print(f"  {n} -> group {group}")

Solution

  • As I understand, you want the code that analyzes these patterns. You can modify this code to your needs.

    mapping: dict[int, list[int]] = {
        0: [127, 136, 145, 190, 235, 280, 370, 389, 460, 479, 569, 578, 118, 226, 244, 299, 334, 488, 668, 677, 0, 550],
        1: [128, 137, 146, 236, 245, 290, 380, 470, 489, 560, 678, 579, 119, 155, 227, 335, 344, 399, 588, 669, 100, 777],
        2: [129, 138, 147, 156, 237, 246, 345, 390, 480, 570, 679, 589, 110, 228, 255, 336, 499, 660, 688, 778, 200, 444],
        3: [120, 139, 148, 157, 238, 247, 256, 346, 490, 580, 670, 689, 166, 229, 337, 355, 445, 599, 779, 788, 300, 111],
        4: [130, 149, 158, 167, 239, 248, 257, 347, 356, 590, 680, 789, 112, 220, 266, 338, 446, 455, 699, 770, 400, 888],
        5: [140, 159, 168, 230, 249, 258, 267, 348, 357, 456, 690, 780, 113, 122, 177, 339, 366, 447, 799, 770, 500, 555],
        6: [123, 150, 169, 178, 240, 259, 268, 349, 358, 457, 367, 790, 114, 277, 330, 448, 466, 556, 880, 899, 600, 222],
        7: [124, 160, 179, 250, 269, 278, 340, 359, 368, 458, 467, 890, 115, 133, 188, 223, 377, 449, 557, 566, 700, 999],
        8: [125, 134, 170, 189, 260, 279, 350, 369, 378, 459, 567, 468, 116, 224, 233, 288, 440, 477, 558, 990, 800, 666],
        9: [126, 135, 180, 234, 270, 289, 360, 379, 450, 469, 117, 478, 568, 144, 199, 225, 388, 559, 577, 667, 900, 333],
    }
    
    msgs: list[str] = [
        "560-1X490-3",
        "238-3X458-7",
        "667-9X560-1",
        "170-8X233-8",
        "570-2X155-1"
    ]
    
    def validate(msg: str) -> bool:
        return all([
            isinstance(msg, str),
            len(msg) == 11,
            msg[:3].isdigit(),
            msg[4].isdigit(),
            msg[6:9].isdigit(),
            msg[10].isdigit(),
            msg[3] == "-",
            msg[5] == "X",
            msg[9] == "-"
        ])
    
    def search(num: int, mapping: dict[int, list[int]]) -> list[int]:
        groups: list[int] = []
        for i, values in enumerate(mapping.values()):
            if num in values:
                groups.append(i)
    
        return groups
    
    
    def prepare_data(msg: str) -> list[int]:
        if not validate(msg):
            raise ValueError(f"There is error in format of msg: {msg}")
        return [int(num) for num in [msg[:3], msg[4], msg[6:9], msg[10]]]
    
    
    def analysis(
        msg: str, mapping: dict[int, list[int]]
    ) -> dict[int, list[int] | None]:
        nums: list[int] = prepare_data(msg)
    
        return {num: search(num, mapping) for num in nums}
    
    
    def display(msg: str, mapping: dict[int, list[int]]) -> str:
        analysed: str = ""
    
        for num, group in analysis(msg, mapping).items():
            group = [str(item) for item in group or ["None"]]
            analysed += f"  {num} -> group {', '.join(group)}.\n\n"
    
        return  f"Message {msg}\n\n{analysed}"
    
    
    def display_all(msgs: list[str], mapping: dict[int, list[int]]) -> str:
        return "\n".join([display(msg, mapping) for msg in msgs])
    
    
    if __name__ == "__main__":
        print(display_all(msgs, mapping))