假設你沒有看到加載整個文件的問題,假設您解決您的正則表達式(你提出它的程序將打破不匹配,你應該檢查是否有一個匹配,如果不的方式有一組在其內)這兩個是不一樣。考慮你的文件存在的第一行:
PubNo | Name | CoverID | Issue | CustomLabel | Split | SomethingMore
你的正則表達式「驗證」將迎來它的成功,您的字符串比較不會。如果你希望你的第一列「驗證」精確該字符串,沒有別的匹配,你有你的正則表達式模式更改爲r"\|?PubNo\|Name\|CoverID\|Issue\|CustomLabel\|Split\|?$"
。此外,您的正則表達式'驗證程序'將消耗「替換」部分中的所有空白字符,包括製表符,而字符串比較器不會。
所有的事情都是平等的 - 字符串搜索將是大大在這兩種情況下更快 - 這是不計算正則表達式引擎的裝載,準備圖案和所需的所有其他支持結構。即使緩存模式,並刪除了正則表達式的所有缺點,字符串比較仍然會更快。考慮像設置:
import re
VALID = "PubNo|Name|CoverID|Issue|CustomLabel|Split"
# prepare the regex patterns
PATTERN_VALID = re.compile(r"\|?{}\|?".format(VALID.replace("|", r"\|")))
PATTERN_STRICT = re.compile(PATTERN_VALID.pattern + "$", re.I)
CLEAR_WHITESPACE = re.compile(r"\s")
# let's not disadvantage the string compare, too
VALID_LOWER = VALID.lower()
def string_valid(data):
if data.strip("| ").replace(" ", "").lower().startswith(VALID_LOWER):
return True
return False
def string_valid_strict(data):
if data.strip("| \r\n").replace(" ", "").lower() == VALID_LOWER:
return True
return False
def regexp_valid(data):
if PATTERN_VALID.match(CLEAR_WHITESPACE.sub("", data)):
return True
return False
def regexp_valid_strict(data):
if PATTERN_STRICT.match(CLEAR_WHITESPACE.sub("", data)):
return True
return False
這將涵蓋例,這兩種方法(嚴格匹配僅僅是起步)。你沒有考慮建立你的正則表達式忽略空格,這樣你就不需要替換,但也不會大幅加速它(實際上,它可能會比這還慢)。
所以,現在,如果你有3個文件,說是涵蓋所有三種情況下good.txt
,strict.txt
和bad.txt
,你可以運行這樣一個特設的測試:
# open test files and only get the first lines
with open("good.txt", "r") as g, open("strict.txt", "r") as s, open("bad.txt", "r") as b:
g = g.readline() # overwrite is perfectly fine for our test
s = s.readline() # overwrite is perfectly fine for our test
b = b.readline() # overwrite is perfectly fine for our test
# make sure our functions perform adequately
assert string_valid(g) is regexp_valid(g) is True
assert string_valid_strict(g) is regexp_valid_strict(g) is False
assert string_valid(s) is regexp_valid(s) is True
assert string_valid_strict(s) is regexp_valid_strict(s) is True
assert string_valid(b) is regexp_valid(b) is False
assert string_valid_strict(b) is regexp_valid_strict(b) is False
如果你的時間爲每個電話那些(所以3個電話,每個循環3條不同的線路)超過,比如說,10圈的你:
Python 2.7.11
string_valid: 100,000 loops: 0.31 s, per loop: 3.15 µs
string_valid_strict: 100,000 loops: 0.27 s, per loop: 2.76 µs
regexp_valid: 100,000 loops: 1.34 s, per loop: 13.44 µs
regexp_valid_strict: 100,000 loops: 1.38 s, per loop: 13.83 µs
==
Python 3.5.1
string_valid: 100,000 loops: 0.37 s, per loop: 3.73 µs
string_valid_strict: 100,000 loops: 0.33 s, per loop: 3.37 µs
regexp_valid: 100,000 loops: 1.13 s, per loop: 11.28 µs
regexp_valid_strict: 100,000 loops: 1.22 s, per loop: 12.17 µs
這是正則表達式最好的情況下 - 我們甚至編制空白刪除模式。 OTOH,字符串搜索可以進一步優化(對於非嚴格示例,切片代替startswith()
等)。
正則表達式很好,但只有在需要的時候。沒有理由利用正則表達式來解決像這樣的簡單問題。
對於初學者 - 你爲什麼要讀整個文件只是爲了「驗證」的第一線? – zwer
,因爲經過驗證,假設它是有效的,文件將被讀入。這不是我關心的地方,當然,正確的有效方法是讀取第一行,驗證,然後讀取其餘部分。我是隻對驗證線路本身的優點/缺點感興趣 – Turk