當我不知道分隔符是否多次存在時,如何提取子字元串?
我有一列具有這種模式的字元串
<email> - <id>
我想只提取電子郵件地址,但這裡的問題是電子郵件地址也可以包含連字元,所以我不能確定分隔符只會出現一次。
所以基本上我想匹配 .* 直到最後一個連字元並將其提取為電子郵件
我有一列具有這種模式的字元串-
這就是你最大的問題。
您在一個欄位中有**兩位數據,這從根本上是個壞主意。
在決定如何儲存任何數據之前,您應該問的第一個問題是
我將如何訪問這些數據?
你真的應該在兩個單獨的欄位中擁有它,然後這個“提取”問題就會“消失”。
數據庫非常非常擅長查找少量數據並將它們組合在一起。
他們通常在尋找大量數據並將它們分開時非常垃圾。
您可以執行以下操作(下面的所有程式碼都可以在此處的小提琴中找到):
CREATE TABLE test ( field VARCHAR (200) NOT NULL );
填充一些範例數據:
INSERT INTO test VALUES ('<pol@blah.com> - <1345>'), ('<xyz@blah.com> - <1345>'), ('<rubbish> - <abc@blah.com> - <1345>'), ('<more_rubbish> - <zyx1234@blah.com> - <1345>');
然後執行:
SELECT REGEXP_SUBSTR ( field, '[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}') AS email FROM test;
結果:
email pol@blah.com xyz@blah.com abc@blah.com zyx1234@blah.com
現在,我用於電子郵件的簡單
[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}
正則表達式是- 您可以根據需要/要求將其複雜化 - 請參見此處- 連結到的一個正則表達式解決方案有 6,500 個字元,也許是矯枉過正?搜尋將使您在解決方案健壯和適合您之間做出妥協。請注意,正則表達式很昂貴,並且根據您的表大小和字元串的長度,您的查詢可能會很慢。您可以使用 s 以犧牲一點磁碟空間為代價來減少查詢時間成本,
GENERATED COLUMN
如下所示:CREATE TABLE test_bis ( field VARCHAR (200) NOT NULL, email VARCHAR (200) AS ( REGEXP_SUBSTR ( field, '[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}' ) ) PERSISTENT -- HDD cost, also works with VIRTUAL - CPU cost. );
做了同樣的
INSERT
事情 - 見小提琴,結果是:field email <pol@blah.com> - <1345> pol@blah.com <xyz@blah.com> - <1345> xyz@blah.com <rubbish> - <abc@blah.com> - <1345> abc@blah.com <more_rubbish> - <zyx1234@blah.com> - <1345> zyx1234@blah.com
您可以索引此
PERSISTENT
欄位以加快搜尋速度:CREATE INDEX fb_regex_email ON test_bis (email);
據我所知,MariaDB 還沒有功能(或表達式)索引(例如,參見PostgreSQL )。
如果您不想犧牲 HDD 空間,您可以改為創建
GENERATED
列VIRTUAL
- 以 CPU 週期為代價 - *à vous le choix!*我無法測試索引,因為範例表非常小,以至於 MySQL 無論如何都會進行表掃描,無論索引是否存在。我只是建議您使用自己的硬體和自己的數據測試這些解決方案,以確保您的性能對於您的要求/約束是最佳的。