是否有与 PHP 的 preg_replace 等效的 MySQL?

Posted

技术标签:

【中文标题】是否有与 PHP 的 preg_replace 等效的 MySQL?【英文标题】:Is there a MySQL equivalent of PHP's preg_replace? 【发布时间】:2010-12-14 21:28:57 【问题描述】:

我有一个匹配 mysql 中的一个字段,我认为我可以使用正则表达式,但似乎 MySQL 没有我需要的功能来完成这项工作。这是场景:

我在 php 中有一个名为 $url 的变量。假设这个变量被设置为字符串“/article/my-article/page/2”。我在 MySQL 中还有一个 URL 表,我想从中提取内容。但是,存储在我的表中的 URL 包含通配符。

以前,我进行了此设置,以便存储在表中的值如下所示:“/article/%/page/%”。

使用该配置,我可以运行:

SELECT * FROM urls WHERE '$url' LIKE url

这将匹配,这是所需的功能。

我现在想做的是允许一个更高级的通配符,这样我的 MySQL 数据可以是“/article/slug/page”而不是“/article/%/page/%” /page_no"。

我想创建一个与该数据匹配的 SQL 查询,使用相同的 $url 输入。 LIKE 不再是正确的比较,因为我没有使用内置的“%”通配符,而是 .*。任何想法如何做到这一点?

【问题讨论】:

【参考方案1】:

从mysql 5.5开始,可以使用RLIKE:

要么以 REGEXP 样式存储 url,并使用

进行查询

SELECT * FROM urls WHERE '$url' RLIKE url;

或保持 LIKE 样式,并进行替换(% by .* , _ by .):

SELECT * FROM urls WHERE '$url' RLIKE REPLACE(REPLACE(url, '%', '.*'), '_', '.');

要完整,您必须进行其他替换以转义正则表达式有效的字符:? \ () [] ...(见php函数preg_quote)

【讨论】:

【参考方案2】:

上面的用户 sagi 提到了http://www.mysqludf.org/lib_mysqludf_preg/,但由于这个答案和大多数教程一样非常古老,为了这个问题的新手,我想对此进行扩展。

首先,图书馆真的很棒,从经验来看,我可以说它似乎得到了维护,并且在 2015 年仍然可以完美运行。

为了安装和运行它,我只能找到一些非常过时的教程,所以我想分享一下我所做的对我在 Ubuntu 14.04 上安装最新稳定版本 (v1.1) 有用:

apt-get update
apt-get install libpcre3-dev libmysqlclient-dev build-essential libmysqld-dev libpcre3-dev
wget https://github.com/mysqludf/lib_mysqludf_preg/archive/lib_mysqludf_preg-1.1.tar.gz
tar -xzf lib_mysqludf_preg-1.1.tar.gz
cd lib_mysqludf_preg-1.1
./configure
make  install
make installdb
service mysql restart

您现在应该可以使用以下所有功能:

lib_mysqludf_preg_info
preg_capture
preg_check
preg_replace
preg_rlike
preg_position

【讨论】:

在github.com/mysqludf/lib_mysqludf_preg/blob/testing/INSTALL的github INSTALL 文档中也有一套相当不错的安装说明【参考方案3】:

听起来您想要做的是在数据库中使用新语法,其中 URL 具有您将传递给基于 php (sprintf) 的变量替换代码的占位符,但仍然能够进行原始比较以匹配网址。

如果我理解正确,您想采用新的 URL 格式

/article/slug/page/page_no

并将其与类似的东西匹配

/article/my-article/page/2

提到的 preg 插件 sagi 可以进行您需要的替换,这会将您新格式化的 URL 之一转换为您用于使用 LIKE 语法确定匹配的原始格式。以下查询:

SELECT PREG_REPLACE('/(.*?)/', '%', `url`) FROM urls;

会将新的网址 (/article/slug/page/page_no) 变成原来的样子

/article/%/page/%

然后可以通过您的原始查询反馈,如下所示:

SELECT * FROM urls
WHERE '/article/my-article/page/2' LIKE preg_replace('/(.*?)/', '%', `url`);

MAMP、XAMMP 等一些二进制发行版已经安装了该插件,但它并未安装在 Macports / Ubuntu 等很多系统上。这里有几篇关于安装 preg 插件的文章。希望对您有所帮助。

http://quickshiftin.com/blog/2011/04/installing-mysql-preg-plugin-osx-macports/

http://quickshiftin.com/blog/2011/12/installing-the-mysql-preg-plugin-on-ubuntu-with-apt-get/

【讨论】:

【参考方案4】:

有一个用户定义函数库,可以在 MySQL 中为您提供 preg_replace: http://www.mysqludf.org/lib_mysqludf_preg/

【讨论】:

【参考方案5】:

我找到了解决方案。这并不理想,但我会把它放在这里,以防纯 SQL 解决方案永远不会出现。我可以让 MySQL 中的 url 字段等于“/articles/%/page/%”,并添加另一个名为 variables 的字段,该字段存储要使用的变量名称列表。这样我就可以使用我的原始查询,然后在我检索数据后用 sprintf 在 PHP 中将返回值中的“%”字符替换为“variable”。

不过,如果可能的话,我希望在 SQL 中解决这个问题,因为我认为这个概念很有价值。

【讨论】:

以上是关于是否有与 PHP 的 preg_replace 等效的 MySQL?的主要内容,如果未能解决你的问题,请参考以下文章

PHP preg_replace - 正则表达式

PHP7 preg_replace出错及解决办法

preg_replace 这个:123.. - 可能是一个简单的 PHP / preg_replace / RegEx 问题,但老实说我很难过

PHP 在 preg_replace 上崩溃

php preg_replace遇到替换本身有括号的内容怎么办

PHP:输出一行不带preg_replace的HTML文档