代码之家  ›  专栏  ›  技术社区  ›  ClaytonSummitt

Regex代码,用于识别后面跟着复杂模式的关键字(来自可变的人工输入)

  •  0
  • ClaytonSummitt  · 技术社区  · 1 年前

    我正在进行一个NLP项目,其中的数据需要对PII进行一些清理。我使用spaCy NER来处理日期和名称,但我需要找到后面跟着字母数字的(不区分大小写)Room的实例。我有一些东西是有效的,但它非常丑陋。我从一位同事那里继承了一个模式,但他们错过了很多模式,会抓住这样的东西 The room was... 和miss room 16b/16a/16c 。我正在使用python 3.X环境。

    我正在努力学习并尽我所能使用regex101。虽然这种模式主要用于查找房间后面的字母数字模式,但会抓取房间后面的任何单词,这是不希望的。 The room was cleaned 变成 The room number cleaned 。我认为 \w? 是不希望的原因。我在 ?\w? ? 并且不认为它是有效的,也不容易理解正在发生的事情。

    我的模式

    (room|rm) ?(#|number|no.?)? ?\w? ?(\d+|[a-z0-9\-?\/\(\) ]{2,5})[a-z]?| (room?) ([0-9]+[a-z/]+)+| room? [a-z]?[0-9/]+
    

    和示例

    room (b7)
    rm 2
    rm no 4
    room a12
    Room 12
    Roomd25
    room D25
    ROOM D25
    ROOM C-11
    room 17
    room A4B
    room 101
    rm #17 
    room 37/39
    ROOM B-1
    room C 29 from 
    room C23/25/27
    room 16b/18a/18b
    Clean the room now _AVOID_
    
    1 回复  |  直到 1 年前
        1
  •  0
  •   BeGreen    1 年前

    Regex对于自定义的人工输入可能很难看,因为我们是人,所以我们键入不同的东西。如果可能,请在存储数据之前尝试清理数据。

    也许将所有内容都设为小写,替换 rm 具有 room 。删除字符串中的任何非字母数字字符。我肯定会在做regex之前先做这件事。

    import re
    
    def clean_data(text):
        text = text.lower()
        text = text.replace("rm", "room")
        return re.sub(r'[^a-zA-Z0-9 ]', '', text)
    
    pattern = r'\b(room|rm)\b\s*([#]?|number|no.?|[\w/()]*\w)\s*([a-zA-Z0-9-]+)\b'
    
    text = ['room b7', 'rm 2', 'not a room fsd', 'rm no 4', 'room a12', 'Room 12', 'Roomd25', 'room D25', 'ROOM D25', 'ROOM C11', 'room 17', 'room A4B', 'room 101', 'rm 17', 'room 37/39', 'ROOM B1', 'room C 29 from', 'room C23/25/27', 'room 16b/18a/18b', 'and other sentences that should be left intact like Clean the room now AVOID.']
    
    ny_text = [clean_data(t) for t in text]
    
    
    for t in ny_text:
        match = re.findall(pattern, t, re.IGNORECASE)
        if not match:
            continue
        room_alias = match[0][0]
        room_number = match[0][2]
        print(f"Found: {room_alias} {room_number}")