我有一個MySQL數據庫和我有一個查詢爲:MySQL的 - 返回匹配模式的REGEXP查詢
SELECT `id`, `originaltext` FROM `source` WHERE `originaltext` regexp '[0-9][0-9]'
這個探測與在它2個位數編號的所有originaltexts。
我需要mysql返回這些數字作爲字段,所以我可以進一步操縱它們。理想情況下,如果我可以添加額外的標準應該是> 20會很好,但我也可以單獨做到這一點。
我有一個MySQL數據庫和我有一個查詢爲:MySQL的 - 返回匹配模式的REGEXP查詢
SELECT `id`, `originaltext` FROM `source` WHERE `originaltext` regexp '[0-9][0-9]'
這個探測與在它2個位數編號的所有originaltexts。
我需要mysql返回這些數字作爲字段,所以我可以進一步操縱它們。理想情況下,如果我可以添加額外的標準應該是> 20會很好,但我也可以單獨做到這一點。
如果您想在數據庫中使用更多正則表達式,可以考慮使用LIB_MYSQLUDF_PREG。這是一個導入PCRE庫的MySQL用戶函數的開源庫。 LIB_MYSQLUDF_PREG僅以源代碼形式提供。要使用它,你需要能夠編譯它並將其安裝到MySQL服務器中。安裝這個庫不會以任何方式改變MySQL的內置正則表達式支持。它僅提供以下附加功能:
PREG_CAPTURE從字符串中提取正則表達式匹配。 PREG_POSITION返回正則表達式與字符串匹配的位置。 PREG_REPLACE對字符串執行搜索和替換。 PREG_RLIKE測試一個正則表達式是否匹配一個字符串。
所有這些函數都將正則表達式作爲它們的第一個參數。這個正則表達式必須像Perl正則表達式運算符那樣格式化。例如。要測試正則表達式是否與主題不區分大小寫匹配,可以使用MySQL代碼PREG_RLIKE('/ regex/i',subject)。這與PHP的preg函數類似,這些函數還需要PHP字符串內正則表達式的額外//分隔符。
如果你想要更簡單的東西,你可以改變這個功能,以更好地滿足你的需求。
CREATE FUNCTION REGEXP_EXTRACT(string TEXT, exp TEXT)
-- Extract the first longest string that matches the regular expression
-- If the string is 'ABCD', check all strings and see what matches: 'ABCD', 'ABC', 'AB', 'A', 'BCD', 'BC', 'B', 'CD', 'C', 'D'
-- It's not smart enough to handle things like (A)|(BCD) correctly in that it will return the whole string, not just the matching token.
RETURNS TEXT
DETERMINISTIC
BEGIN
DECLARE s INT DEFAULT 1;
DECLARE e INT;
DECLARE adjustStart TINYINT DEFAULT 1;
DECLARE adjustEnd TINYINT DEFAULT 1;
-- Because REGEXP matches anywhere in the string, and we only want the part that matches, adjust the expression to add '^' and '$'
-- Of course, if those are already there, don't add them, but change the method of extraction accordingly.
IF LEFT(exp, 1) = '^' THEN
SET adjustStart = 0;
ELSE
SET exp = CONCAT('^', exp);
END IF;
IF RIGHT(exp, 1) = '$' THEN
SET adjustEnd = 0;
ELSE
SET exp = CONCAT(exp, '$');
END IF;
-- Loop through the string, moving the end pointer back towards the start pointer, then advance the start pointer and repeat
-- Bail out of the loops early if the original expression started with '^' or ended with '$', since that means the pointers can't move
WHILE (s <= LENGTH(string)) DO
SET e = LENGTH(string);
WHILE (e >= s) DO
IF SUBSTRING(string, s, e) REGEXP exp THEN
RETURN SUBSTRING(string, s, e);
END IF;
IF adjustEnd THEN
SET e = e - 1;
ELSE
SET e = s - 1; -- ugh, such a hack to end it early
END IF;
END WHILE;
IF adjustStart THEN
SET s = s + 1;
ELSE
SET s = LENGTH(string) + 1; -- ugh, such a hack to end it early
END IF;
END WHILE;
RETURN NULL;
END
MySQL中沒有任何使用正則表達式提取文本的語法。您可以使用REGEXP來標識包含兩個連續數字的行,但要解壓縮它們,您必須使用在這種情況下非常困難的普通字符串操作函數。
替代方案:
SUBSTRING(originaltext from '%#[0-9]{2}#%' for '#')
。我同意。我的直覺是從數據庫中獲取整個字段,然後使用腳本將其與正則表達式進行比較並提取匹配。 – dgmdan 2012-02-01 15:55:42
我有同樣的問題,這是我找到的解決方法(但它不會在所有情況下工作):
LOCATE()
找到開頭和結尾部分字符串你wan't匹配MID()
提取子之間...這裏的一個例子可能會有所幫助 – Geoff 2015-03-03 18:34:57
我用我的代碼作爲存儲過程(函數),應該工作以提取任何數字在一個塊中建立的數字。這是我更廣泛的圖書館的一部分。
DELIMITER $$
-- 2013.04 [email protected]
-- FindNumberInText("ab 234 95 cd", TRUE) => 234
-- FindNumberInText("ab 234 95 cd", FALSE) => 95
DROP FUNCTION IF EXISTS FindNumberInText$$
CREATE FUNCTION FindNumberInText(_input VARCHAR(64), _fromLeft BOOLEAN) RETURNS VARCHAR(32)
BEGIN
DECLARE _r VARCHAR(32) DEFAULT '';
DECLARE _i INTEGER DEFAULT 1;
DECLARE _start INTEGER DEFAULT 0;
DECLARE _IsCharNumeric BOOLEAN;
IF NOT _fromLeft THEN SET _input = REVERSE(_input); END IF;
_loop: REPEAT
SET _IsCharNumeric = LOCATE(MID(_input, _i, 1), "") > 0;
IF _IsCharNumeric THEN
IF _start = 0 THEN SET _start = _i; END IF;
ELSE
IF _start > 0 THEN LEAVE _loop; END IF;
END IF;
SET _i = _i + 1;
UNTIL _i > length(_input) END REPEAT;
IF _start > 0 THEN
SET _r = MID(_input, _start, _i - _start);
IF NOT _fromLeft THEN SET _r = REVERSE(_r); END IF;
END IF;
RETURN _r;
END$$
如果你想返回一個字符串的一部分:
SELECT id , substring(columnName,(locate('partOfString',columnName)),10) from tableName;
Locate()
將返回匹配字符串的開頭現在的位置成爲首發的Function Substring()
位置我知道這是相當一段時間以來,這個問題被問到,但遇到它,並認爲這將是我的自定義正則表達式替代品一個很好的挑戰 - 見this blog post。
...好消息是它可以,但它需要被稱爲不少次。請參閱this online rextester demo,其中顯示了下面SQL的工作方式。
SELECT reg_replace(
reg_replace(
reg_replace(
reg_replace(
reg_replace(
reg_replace(
reg_replace(txt,
'[^0-9]+',
',',
TRUE,
1, -- Min match length
0 -- No max match length
),
'([0-9]{3,}|,[0-9],)',
'',
TRUE,
1, -- Min match length
0 -- No max match length
),
'^[0-9],',
'',
TRUE,
1, -- Min match length
0 -- No max match length
),
',[0-9]$',
'',
TRUE,
1, -- Min match length
0 -- No max match length
),
',{2,}',
',',
TRUE,
1, -- Min match length
0 -- No max match length
),
'^,',
'',
TRUE,
1, -- Min match length
0 -- No max match length
),
',$',
'',
TRUE,
1, -- Min match length
0 -- No max match length
) AS `csv`
FROM tbl;
嗯 - 我不認爲這是明顯的在我原來的職位,但原文已經得到了大量的文字「絨毛」的周圍數...我需要「解壓」的個數出來的。並且可能有一個原始文本中有多個數字... – Steve 2011-03-19 10:24:21
我已更新答案。 – Pentium10 2011-03-19 10:36:32