[英]Python: Validate Regex, find a match inside string
我們有一個發票編號規則,我們想對其進行一些修改。
在用戶設置中,有一個設置用戶發票編號格式的設置,我們可以讓用戶更改他想要的任何內容,但是我們有一個發票創建頁面,在頁面內部我們只想允許用戶將數字更改為更高一點。
例如:
在設置內部,規則設置為CN-002/2021
。 在發票創建頁面中,用戶嘗試將規則更改為CN-001/2021
,在這種情況下,我們將拋出錯誤,因為我們不希望這樣做。 如果用戶嘗試將規則更改為CN-003/2021
,我們允許。
注意:用戶不能更改任何其他內容,例如CZ-003/2021
或CN-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
。
我建議進一步驗證中間數字。 例如,您可以確保:
nmid
的字符數與omid
相同nmid
完全由數字組成您可能還想從validate
function 返回一條消息,以報告驗證實際出了什么問題(例如,“更改發票編號的開頭是非法的”)。
您也可以考慮更正一些更改。 例如,如果用戶嘗試將"CN"
修改為"CZ"
,但輸入在其他方面有效,則您可能只想接受他們的更改,但將nst
替換為ost
。 更進一步,我建議甚至不允許用戶輸入發票號碼的開始和結束部分,而是要求他們輸入一個新號碼num
,然后將新發票號碼創建為f"{ost}-{num}/{oend}"
如果發票編號的格式沒有改變,您可以通過執行str.split()
幾次來檢查數字是更高還是更低......
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.