簡體   English   中英

Python:驗證正則表達式,在字符串中找到匹配項

[英]Python: Validate Regex, find a match inside string

我們有一個發票編號規則,我們想對其進行一些修改。

在用戶設置中,有一個設置用戶發票編號格式的設置,我們可以讓用戶更改他想要的任何內容,但是我們有一個發票創建頁面,在頁面內部我們只想允許用戶將數字更改為更高一點。

例如:

在設置內部,規則設置為CN-002/2021 在發票創建頁面中,用戶嘗試將規則更改為CN-001/2021 ,在這種情況下,我們將拋出錯誤,因為我們不希望這樣做。 如果用戶嘗試將規則更改為CN-003/2021 ,我們允許。

注意:用戶不能更改任何其他內容,例如CZ-003/2021CN-001/2022

  • 檢查號碼是否已更改: if old_invoice_no != new_invoice_no
  • 找出哪個號碼發生了變化,例如舊號碼是CN-001/2021 ,新號碼是CN-002/2021 對於這種情況,我們會通過,因為我們只允許數字更高而從不更低。 如果新編號為CN-000/2021 ,我們將拋出錯誤,因為編號較低。

如何檢查數字是否不低?

這是整個代碼:

def update(self, instance, validated_data):
    old_invoice_no = instance.number # Output CN-002/2021
    new_invoice_no = validated_data.get("number") # CN-001/2021

    if old_invoice_no != new_invoice_no:
        # .. Now the number has changed, how can we find the new number which was changed?
        # The number which has changed is 001 to 002

        # If the number format didn't match we throw an error
        return ValidationError("msg_error_malformed_invoice_number_pattern")

    # Everything seems good, we can update the instance
    validated_data = self._update_validated_data(validated_data)
    instance = super().update(instance, validated_data)
    self._update_customer(validated_data, instance)
    return instance

這是一個有效的解決方案

import re

def validate(old, new):
    ost, omid, oend = re.split("[-/]", old)
    nst, nmid, nend = re.split("[-/]", new)
    if ost != nst or oend != nend:
        return False
    elif int(nmid) < int(omid):
        return False
    else:
        return True 

x = "CN-001/2021"
y = "CN-000/2021"
print(validate(x, y))
# False

x = "CN-001/2021"
y = "CN-002/2021"
print(validate(x, y))
# True

在這里,我們在-/處拆分字符串,因此"CN-001/2021"變為["CN", "001", "2021"] 我在這里將變量名命名為 start、middle 和 end( ost表示“old start”, omid表示“old mid”,等等......)。 如果客戶輸入了無效條目,則此代碼返回False ,如果他們的輸入有效,則返回True

我建議進一步驗證中間數字。 例如,您可以確保:

  1. nmid的字符數與omid相同
  2. nmid完全由數字組成

您可能還想從validate function 返回一條消息,以報告驗證實際出了什么問題(例如,“更改發票編號的開頭是非法的”)。

您也可以考慮更正一些更改。 例如,如果用戶嘗試將"CN"修改為"CZ" ,但輸入在其他方面有效,則您可能只想接受他們的更改,但將nst替換為ost 更進一步,我建議甚至不允許用戶輸入發票號碼的開始和結束部分,而是要求他們輸入一個新號碼num ,然后將新發票號碼創建為f"{ost}-{num}/{oend}"

如果發票編號的格式沒有改變,您可以通過執行str.split()幾次來檢查數字是更高還是更低......

所以你的代碼可以在python3中這樣修改

def update(self, instance, validated_data):
    old_invoice_no = instance.number # Output CN-002/2021
    new_invoice_no = validated_data.get("number") # CN-001/2021

    if old_invoice_no != new_invoice_no:
        if(int((new_invoice_no.split('/')[0]).split('-')[1]) < int((old_invoice_no.split('/')[0]).split('-')[1]) or (new_invoice_no.split('/')[0]).split('-')[0] != (old_invoice_no.split('/')[0]).split('-')[0] or new_invoice_no.split('/')[1] != old_invoice_no.split('/')[1]):
          # New number invalid
          return ValidationError("msg_error_malformed_invoice_number_pattern")

    # Everything seems good, we can update the instance
    validated_data = self._update_validated_data(validated_data)
    instance = super().update(instance, validated_data)
    self._update_customer(validated_data, instance)
    return instance

如果您使用的是 python 的早期版本,那么您需要使用string.atoi()而不是if中的int()強制轉換。 以上也僅檢查您具體要求的內容。 這會以相同的方式多次拆分字符串,但假設更改不是很頻繁。 不應該成為您的應用程序的瓶頸。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM