亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

使用 python 和 javascript 的正則表達式速度慢,但在 go 和 php 中快速失敗

使用 python 和 javascript 的正則表達式速度慢,但在 go 和 php 中快速失敗

Go
翻閱古今 2023-03-21 15:21:00
我寫了一個正則表達式來解析 PostgreSQL 錯誤,試圖向用戶顯示哪個字段有重復數據。正則表達式是這個:^DETAIL:.[^\(]+.(.[^\)]+).[^\(]+.(.[^\)]+). already exists如果你像這樣針對正確的消息運行它,它會非??欤╤ttps://regex101.com/r/GZuREV/1):ERROR:  duplicate key value violates unique constraint "uq_content_block_internal_name_store_id" DETAIL:  Key (lower(internal_name::text), store_id)=(some content block-32067683, 0c6d20a7-d843-44f3-af9c-4a2cf2a47e4c) already exists.但是,如果 PostgreSQL 發出另一條消息,如下所示,我的機器中 python 將花費大約 30 秒的時間來回答 ( https://regex101.com/r/GZuREV/2 )。ERROR:  null value in column "active" violates not-null constraint DETAIL:  Failing row contains (2018-08-16 14:23:52.214591+00, 2018-08-16 14:23:52.214591+00, null, 6f6d1bc9-c47e-46f8-b220-dae49bd58090, bf24d26e-4871-4335-9f18-83c5a52f1b3a, Some Product-a1c03dde-2de9-401c-92d5-5c1500908984, {"de_DE": "Fugit tempore voluptas quos est vitae.", "en_GB": "Qu..., {"de_DE": "Fuga reprehenderit nobis reprehenderit natus magni es..., {"de_DE": "Fuga provident dolorum. Corrupti sunt in tempore quae..., my-product-53077578, SKU-53075778, 600, 4300dc25-04e2-4193-94c0-8ee97b636739, 52553d24-6d1c-4ce6-89f9-4ad765599040, null, 38089c3c-423f-430c-b211-ab7a57dbcc13, 7d7dc30e-b06b-48b7-b674-26d4f705583b, null, {}, 0, null, 9980, 100, 1, 5).如果轉到 regex101 鏈接,您可以看到,如果您切換到不同的語言,如 php 或 go,它們都很快返回說沒有找到匹配項,但如果您選擇 python 或 javascript,您將超時。我的快速臟修復是這樣的:match = 'already exists' in error_message and compiled_regex.search(error_message)你認為這可能是什么原因造成的?會不會是貪婪的運營商在我達到我想要的數據之前消費?
查看完整描述

4 回答

?
蝴蝶刀刀

TA貢獻1801條經驗 獲得超8個贊

包正則表達式

import "regexp"

包 regexp 實現正則表達式搜索。

接受的正則表達式語法與 Perl、Python 和其他語言使用的通用語法相同。更準確地說,它是 RE2 接受并在https://golang.org/s/re2syntax中描述的語法 ,\C 除外。有關語法的概述,請運行

go doc regexp/syntax

此包提供的正則表達式實現保證按輸入大小線性運行。(這是大多數正則表達式的開源實現不保證的屬性。)有關此屬性的更多信息,請參閱

http://swtch.com/~rsc/regexp/regexp1.html

或任何有關自動機理論的書。


通過設計,Go 正則表達式保證在輸入的大小上按線性時間運行,這是正則表達式的其他一些實現無法保證的屬性。請參閱正則表達式匹配可以簡單快速。


查看完整回答
反對 回復 2023-03-21
?
阿波羅的戰車

TA貢獻1862條經驗 獲得超6個贊

使用這個:

^DETAIL:\s*+Key[^\(]++\((.+)\)[^\(]+\(([^\)]+)\) already exists

查看匹配示例非匹配示例

解釋:

首先,原始正則表達式似乎與整個鍵組不匹配,您停在了lower(internal_name::text,遺漏了復合鍵的某些列以及一個不平衡的括號。如果你這樣修改它,它應該可以捕獲復合鍵。如果不應該這樣做,請告訴我:

^DETAIL:.[^\(]+.(.+)\)[^\(]+.(.[^\)]+). already exists

只需更改它,正則表達式就可以“運行”,但仍然很慢。

他的主要原因之一就是這個[^\(]+。它首先匹配并DETAIL:  Failing row contains(space)繼續匹配正則表達式的其余部分。它不會匹配,所以它回溯到少一個字符,直到DETAIL:  Failing row contains并繼續正則表達式的其余部分。它不會匹配,所以會回到DETAIL:  Failing row contain......等等。

避免這種情況的一種方法是使用所有格量詞。這意味著一旦你獲取了一些東西,你就無法返回。所以使用這個[^\(]++而不是這個[^\(]+(即:)^DETAIL:.[^\(]++.(.+)\)[^\(]+.(.[^\)]+). already exists使正則表達式將步數從 28590 減少到 1290。

但你仍然可以改進它。如果您知道您所需的數據使用關鍵字key,請使用它!這樣,由于它不存在于失敗的示例中,它會使正則表達式很快失?。ㄒ坏┧x取 DETAIL 和下一個詞)

所以如果你使用^DETAIL:\s*+Key[^\(]++.(.+)\)[^\(]+.(.[^\)]+). already exists步驟現在只有 12。

如果您覺得使用key過于具體,您可以使用不太通用的東西來嘗試找到“不是'失敗'”。像這樣:

^DETAIL:\s*+(?!Fail)[^\(]++.(.+)\)[^\(]+.(.[^\)]+). already exists

這樣就是17步。

最后,您可以調整匹配內容的正則表達式。

改變這個:

^DETAIL:\s*+Key[^\(]++.(.+)\)[^\(]+.
           # <============= here, use \( instead
           (.[^\)]+). already exists

這樣:

^DETAIL:\s*+Key[^\(]++.(.+)\)[^\(]+\((.[^\)]+). already exists

這將步驟從 538 減少到 215,因為你減少了回溯。

然后,在刪除幾個無用的點并將一些(應該是括號的)點替換為\(\)(個人品味)之后,您將獲得最終的正則表達式:

^DETAIL:\s*+Key[^\(]++\((.+)\)[^\(]+\(([^\)]+)\) already exists


查看完整回答
反對 回復 2023-03-21
?
DIEA

TA貢獻1820條經驗 獲得超2個贊

這是一個正則表達式怪物:)

為什么不拆分 2 個正則表達式?

  1. 檢查是否already exists匹配(非??欤?/p>

  2. 使用現有的正則表達式提取要顯示的數據^DET.[^\(]+.(.[^\)]+).[^\(]+.(.[^\)]+)

那應該可以大大加快您的代碼速度。(你甚至可以像我一樣縮短細節)


查看完整回答
反對 回復 2023-03-21
?
繁花不似錦

TA貢獻1851條經驗 獲得超4個贊

這并不是問題的真正答案,但我認為問題可能出在貪婪的運營商身上。無論如何,我認為你應該讓它的一部分變得懶惰以快速失敗。

我使用了這種模式,在 regex101 上的所有語言引擎上都可以:

^DETAIL:.+?\((.+)\).+?\((.+)\) already exists.


查看完整回答
反對 回復 2023-03-21
  • 4 回答
  • 0 關注
  • 201 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號