我有一个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