zoukankan      html  css  js  c++  java
  • MySQL必知必会-用正则表达式进行搜索

    用正则表达式进行搜索

    使用MySQL正则表达式

    基本字符匹配

    下面的语句检索列prod_name包含文本1000的所有行:

    输入

    SELECT prod_name
    FROM products
    WHERE prod_name REGEXP '1000'
    ORDER BY prod_name;
    

    输出

    +--------------+
    | prod_name    |
    +--------------+
    | JetPack 1000 |
    +--------------+
    

    分析

    出关键字LIKE被REGEXP替代外,这条语句看上去非常像LIKE的语句。它告诉MySQL:REGEXP后所跟的东西作为正则表达式(与文字正文匹配1000匹配的一个正则表达式)处理。

    在上面的例子中,正则表达式确实没有带来太多好处(可能还会降低性能),不过,请考虑下面的例子:

    输入

    SELECT prod_name
    FROM products
    WHERE prod_name REGEXP '.000'
    ORDER BY prod_name;
    

    输出

    +--------------+
    | prod_name    |
    +--------------+
    | JetPack 1000 |
    | JetPack 2000 |
    +--------------+
    

    分析

    这里使用了正则表达式**.000。**.是正则表达式语言中一个特殊的字符。它表示匹配任意一个字符。

    当然,这个特殊的例子也可以用LIKE和通配符来完成。

    匹配不区分大小写 MySQL中的正则表达式匹配(自版本3.23.4后)不区分大小写(即,大写和小写都匹配)。为区分大小写,可使用BINARY关键字,如WHERE prod_name REGEXP BINARY ‘JetPack .000’。

    进行OR匹配

    为搜索两个串之一(或者为这个串,或者为另一个串),使用|,如下所示:

    输入

    SELECT prod_name
    FROM products
    WHERE prod_name REGEXP '1000|2000'
    ORDER BY prod_name;
    

    输出

    +--------------+
    | prod_name    |
    +--------------+
    | JetPack 1000 |
    | JetPack 2000 |
    +--------------+
    

    分析

    语句中使用了正则表达式1000|2000。|为正则表达式的OR操作符。它表示匹配其中之一。

    两个以上的OR条件 可以给出两个以上的OR条件。例如,'1000|2000|3000’将匹配1000或2000或3000。

    匹配几个字符之一

    匹配任何单一字符。可通过指定一组用[]括起来的字符来完成,如下所示:

    输入

    SELECT prod_name
    FROM products
    WHERE prod_name REGEXP '[123] Ton'
    ORDER BY prod_name;
    

    输出

    +-------------+
    | prod_name   |
    +-------------+
    | 1 ton anvil |
    | 2 ton anvil |
    +-------------+
    

    分析

    [123]定义一组字符,它的意思是匹配1或2或3。

    正如所见,[]是另一种形式的OR语句。事实上,正则表达式[123] Ton为[1|2|3] Ton的缩写,也可以使用后者。但是,需要用[]来定义OR语句查找什么。为更好地理解这一点,请看下面的例子:

    输入

    SELECT prod_name
    FROM products
    WHERE prod_name REGEXP '1|2|3 Ton'
    ORDER BY prod_name;
    

    输出

    +---------------+
    | prod_name     |
    +---------------+
    | 1 ton anvil   |
    | 2 ton anvil   |
    | JetPack 1000  |
    | JetPack 2000  |
    | TNT (1 stick) |
    +---------------+
    

    分析

    这里并不是期望的输出。两个要求的行被检索出来,但还检索出了另外3行。之所以这样是由于MySQL假定你的意思是’1’或’2’或’3 Ton’。除非把字符|括在一个集合中,否则它将应用于整个串。

    字符集也可以被否定,即,它们将匹配除指定字符外的任何东西。为否定一个字符集,在集合的开始处放置一个^即可。因此,尽管[123]匹配字符1、2或3,但[^123]却匹配除这些字符外的任何东西。

    范围匹配

    集合可用来定义要匹配的一个或多个字符。例如,下面的集合将匹配数字0到9:

    [0123456789]

    为简化这种类型的集合,可使用-来定义一个范围。下面的式子功能上等同于上述数字列表:

    [0-9]

    范围不限于完整的集合。此外,范围不一定只是数值的,[a-z]匹配任意字母字符。

    举一个例子:

    输入

    SELECT prod_name
    FROM products
    WHERE prod_name REGEXP '[1-5] Ton'
    ORDER BY prod_name;
    

    输出

    +--------------+
    | prod_name    |
    +--------------+
    | .5 ton anvil |
    | 1 ton anvil  |
    | 2 ton anvil  |
    +--------------+
    

    分析

    这里使用正则表达式[1-5] Ton。[1-5]定义了一个范围,这个表达式意思是匹配1-5,因此返回3个匹配行。由于5 ton匹配,所以返回. 5 ton。

    匹配特殊字符

    输入

    SELECT vend_name
    FROM vendors
    WHERE vend_name REGEXP '.'
    ORDER BY vend_name;
    

    输出

    +----------------+
    | vend_name      |
    +----------------+
    | ACME           |
    | Anvils R Us    |
    | Furball Inc.   |
    | Jet Set        |
    | Jouets Et Ours |
    | LT Supplies    |
    +----------------+
    

    分析

    这并不是期望的输出,.匹配任意字符,因此每个行都被检索出来。

    为了匹配特殊字符,必须用\为前导。\-表示查找-\.表示查找.

    输入

    SELECT vend_name
    FROM vendors
    WHERE vend_name REGEXP '\.'
    ORDER BY vend_name;
    

    输出

    +--------------+
    | vend_name    |
    +--------------+
    | Furball Inc. |
    +--------------+
    

    分析

    这才是期望的输出。\.匹配.,所以只检索出一行。这种处理就是所谓的转义(escaping),正则表达式内具有特殊意义的所有字符都必须以这种方式转义。

    \也用来引用元字符(具有特殊含义的字符),如下表所列。

    元字符 说明
    \f 换页
    \n 换行
    \r 回车
    \t 制表
    \v 纵向制表

    匹配 为了匹配反斜杠字符本身,需要使用\

    或\? 多数正则表达式实现使用单个反斜杠转义特殊字符,以便能使用这些字符本身。但MySQL要求两个反斜杠(MySQL自己解释一个,正则表达式库解释另一个)。

    匹配字符类

    为更方便工作,可以使用预定义的字符集,称为字符类(character class)。下表列出字符类以及它们的含义。

    说明
    [:alnum:] 任意字母和数字(同[a-zA-Z0-9])
    [:alpha:] 任意字符(同[a-zA-Z])
    [:blank:] 空格和制表符(同[ ])
    [:cntrl:] ASCII控制字符(ASCII 0到31和127)
    [:digit:] 任意数字(同[0-9])
    [:graph:] 与[:print:]相同,但不包括空格
    [:lower:] 任意小写字母(同[a-z])
    [:print:] 任意可打印字符
    [:punct:] 既不在[:alnum:]又不在[:cntrl:]中的任意字符
    [:space:] 包括空格在内的任意空白字符(同[\f\n\r\t\v])
    [:unnper:] 任意大写字母(同[A-Z])
    [:xdigit:] 任意十六进制数字(同[a-fA-F0-9])

    匹配多个实例

    表重复元字符

    元字符 说明
    * 0个或多个匹配
    + 1个或多个匹配(等于 {1,})
    ? 0个或1个匹配(等于{0,1})
    {n} 指定数目的匹配
    {n, } 不少于指定数目的匹配
    {n, m} 匹配数目的范围(m不超过255)

    输入

    SELECT prod_name
    FROM products
    WHERE prod_name REGEXP '\([0-9] sticks?\)'
    ORDER BY prod_name;
    

    输出

    +----------------+
    | prod_name      |
    +----------------+
    | TNT (1 stick)  |
    | TNT (5 sticks) |
    +----------------+
    

    分析

    \(匹配(,[0-9]匹配任意数字,sticks?匹配stick和sticks(s后的?使s可选,因为?匹配它前面的任何字符的0次或1次出现),\)匹配)

    输入

    SELECT prod_name
    FROM products
    WHERE prod_name REGEXP '[[:digit:]]{4}'
    ORDER BY prod_name;
    

    输出

    +--------------+
    | prod_name    |
    +--------------+
    | JetPack 1000 |
    | JetPack 2000 |
    +--------------+
    

    分析

    [:digit:]匹配任意数字,因为它为数字的一个集合。{4}确切地要求它前面的字符(任意数字)出现4次,所以[[:digit:]]{4}匹配连在一起的任意4位数字。

    上面的例子也可以如下编写:

    SELECT prod_name
    FROM products
    WHERE prod_name REGEXP '[0-9][0-9][0-9][0-9]'
    ORDER BY prod_name;
    

    定位符

    为了匹配特殊位置的文本,需要使用下表列出的定位符。

    元字符 说明
    ^ 文本的开始
    $ 文本的结尾
    [[:<:]] 词的开始
    [[:>:]] 词的结尾

    输入

    SELECT prod_name
    FROM products
    WHERE prod_name REGEXP '^[0-9\.]'
    ORDER BY prod_name;
    

    输出

    +--------------+
    | prod_name    |
    +--------------+
    | .5 ton anvil |
    | 1 ton anvil  |
    | 2 ton anvil  |
    +--------------+
    

    分析

    ^匹配串的开始。因此,^[0-9\.]只在.或任意数字为串中第一个字符时才匹配它们。

    ^的双重用途 ^有两种用法。在集合中(用[和]定义),用它来否定该集合,否则,用来指串的开始处。

    使REGEXP起类似LIKE的作用 LIKE和REGEXP不同在于,LIKE匹配整个串而REGEXP匹配子串。利用定位符,通过用^开始每个表达式,用$结束每个表达式,可以使REGEXP的作用与LIKE一样。

    简单的正则表达式测试 可以在不使用数据库表的情况下用SELECT来测试正则表达式。REGEXP检查总是返回0(没有匹配)或1(匹配),可以用带文字串的REGEXP来测试表达式,并试验它们,相应的语法如下:

    SELECT 'hello' REGEXP '[0-9]';
    

    这个例子显然将返回0。

    不一定每天 code well 但要每天 live well
  • 相关阅读:
    168. Excel Sheet Column Title
    171. Excel Sheet Column Number
    264. Ugly Number II java solutions
    152. Maximum Product Subarray java solutions
    309. Best Time to Buy and Sell Stock with Cooldown java solutions
    120. Triangle java solutions
    300. Longest Increasing Subsequence java solutions
    63. Unique Paths II java solutions
    221. Maximal Square java solutions
    279. Perfect Squares java solutions
  • 原文地址:https://www.cnblogs.com/geekfx/p/12423064.html
Copyright © 2011-2022 走看看