Python正規表示式提取車牌號

TechSynapse發表於2024-08-22

在Python中使用正規表示式(Regular Expressions)來提取車牌號是一個常見的任務,尤其是在處理車輛資訊或進行影像識別後的文字處理時。中國的車牌號格式多種多樣,但通常包含省份簡稱、英文字母和數字。以下是一個使用Python正規表示式來提取常見中國車牌號(包括新能源車牌)的示例程式碼。

1.簡單程式碼示例

首先,我們需要匯入re模組,這是Python中用於處理正規表示式的標準庫。然後,我們可以編寫一個函式來匹配並提取車牌號。

import re  
  
def extract_license_plates(text):  
    """  
    從給定的文字中提取車牌號。  
    支援普通車牌(如京A12345)和新能源車牌(如京AD12345F)。  
      
    :param text: 包含車牌號資訊的字串  
    :return: 提取到的車牌號列表  
    """  
    # 定義車牌號的正規表示式  
    # 普通車牌:[省份簡稱][A-Z][A-Z0-9]{4}[A-Z0-9掛學警港澳]  
    # 新能源車牌:[省份簡稱][A-DF][A-Z0-9]{5}[DF][A-Z0-9掛學警港澳]  
    plate_pattern = re.compile(r'[京津滬渝冀豫雲遼黑湘皖魯新蘇浙贛鄂桂甘晉蒙陝吉閩貴粵青藏川寧瓊使領A-Z][A-Z](?:(?:[A-Z0-9]{5}[DF])|(?:[DF][A-Z0-9][A-Z0-9]{4}))[A-Z0-9掛學警港澳]')  
      
    # 查詢所有匹配的車牌號  
    plates = plate_pattern.findall(text)  
      
    return plates  
  
# 示例文字  
text = "今天在路上看到了一輛車牌號為京A12345的車和另一輛新能源車牌京AD12345F的車。"  
  
# 呼叫函式並列印結果  
plates = extract_license_plates(text)  
print("找到的車牌號:", plates)

注意

(1)正規表示式說明:

  • 普通車牌號以省份簡稱開始,後面跟著一個大寫字母,然後是5位數字或字母(最後一位可以是掛、學、警、港、澳等特殊字元)。
  • 新能源車牌在省份簡稱後有一個特定的字母(A、D、F),然後是5位數字或字母,最後以D或F開頭,再跟一個字元(同樣可以是掛、學、警、港、澳等特殊字元)。
  • 本示例中簡化了省份簡稱的匹配,直接列出了所有可能的省份簡稱(如“京津滬渝冀豫雲遼黑湘皖魯新蘇浙贛鄂桂甘晉蒙陝吉閩貴粵青藏川寧瓊使領”),實際應用中可能需要更新或動態生成這部分內容。

(2)效能考慮:

  • 如果需要處理大量的文字資料,考慮正規表示式的最佳化和效能影響。
  • 正規表示式編寫時,儘量保持簡潔和精確,避免不必要的回溯和複雜匹配。

(3)實際應用:

  • 在實際應用中,車牌號的格式可能會因地區、時間等因素有所不同,因此正規表示式需要根據實際情況進行調整。
  • 如果車牌號資訊來自影像識別結果,可能需要先對識別結果進行預處理(如去除噪點、歸一化等),以提高正規表示式的匹配準確率。

2.進階程式碼示例

以下是一個更詳細的程式碼示例,它包含了處理多種情況的車牌號提取功能。這個示例中,我將對正規表示式進行微調以更好地匹配普通車牌和新能源車牌,並且會新增一些註釋來解釋程式碼的各個部分。此外,我還會在示例文字中增加一些複雜的情況來測試我們的函式。

import re  
  
def extract_license_plates(text):  
    """  
    從給定的文字中提取車牌號。  
    支援普通車牌(如京A12345)和新能源車牌(如京AD12345F)。  
      
    :param text: 包含車牌號資訊的字串  
    :return: 提取到的車牌號列表  
    """  
    # 定義車牌號的正規表示式  
    # 普通車牌:[省份簡稱][A-Z]([A-Z0-9]{5}[A-Z0-9掛學警港澳])  
    # 新能源車牌:[省份簡稱][A-DF]([A-Z0-9]{4}[DF][A-Z0-9掛學警港澳])  
    # 注意:這裡簡化了新能源車牌的正則,因為新能源車牌第二位可能不是字母D或F,但通常後面會有DF組合  
    # 為了更準確地匹配,我們可以將兩個模式分開  
    normal_plate_pattern = r'[京津滬渝冀豫雲遼黑湘皖魯新蘇浙贛鄂桂甘晉蒙陝吉閩貴粵青藏川寧瓊使領][A-Z][A-Z0-9]{5}[A-Z0-9掛學警港澳]'  
    new_energy_plate_pattern = r'[京津滬渝冀豫雲遼黑湘皖魯新蘇浙贛鄂桂甘晉蒙陝吉閩貴粵青藏川寧瓊使領][A-DF][A-Z0-9]{4}[DF][A-Z0-9掛學警港澳]'  
      
    # 合併為一個正規表示式,使用 | 表示“或”  
    plate_pattern = re.compile(f'({normal_plate_pattern})|({new_energy_plate_pattern})')  
      
    # 查詢所有匹配的車牌號  
    plates = plate_pattern.findall(text)  
      
    # 由於findall返回的是一個元組的列表,其中每個元組包含一個或多個匹配項(取決於正規表示式中有多少捕獲組)  
    # 在這個例子中,我們有兩個捕獲組,但只關心其中一個有值的情況(即匹配到的是普通車牌還是新能源車牌)  
    # 因此,我們需要從每個元組中提取出實際的車牌號  
    clean_plates = [match[0] if match[0] else match[1] for match in plates]  
      
    return clean_plates  
  
# 示例文字,包含多種車牌號  
text = "今天在路上看到了車牌號為京A12345的燃油車,還有新能源車牌京AD12345F和一輛蘇B23456警的警車。"  
  
# 呼叫函式並列印結果  
plates = extract_license_plates(text)  
print("找到的車牌號:", plates)

注意:

(1)我將新能源車牌的正規表示式進行了調整,以更準確地匹配新能源車牌的常見格式。但請注意,實際中的新能源車牌格式可能更加多樣,因此這個正規表示式可能需要進一步調整以適應所有情況。

(2)在處理findall返回的結果時,我使用了列表推導式來遍歷所有匹配項,並從每個元組中提取出實際的車牌號。這是因為當正規表示式中有多個捕獲組時,findall會返回一個包含元組的列表,每個元組包含與每個捕獲組相匹配的文字。在這個例子中,每個元組要麼第一個元素有值(匹配到普通車牌),要麼第二個元素有值(匹配到新能源車牌),因此我們使用條件表示式來從中提取出車牌號。

(3)示例文字中包含了多種車牌號,包括普通車牌、新能源車牌和特殊車輛(警車)的車牌,以測試函式的健壯性。

相關文章