<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??一站式輕松地調用各大LLM模型接口,支持GPT4、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                # 9.7\. 模式匹配 PostgreSQL提供了三種實現模式匹配的方法: 傳統SQL的`LIKE`操作符、SQL99 新增的 `SIMILAR TO`操作符、POSIX風格的正則表達式。 除了基本的"這個字符串匹配這個模式"操作符之外, 也可以使用函數抽取或替換匹配的子字符串并且在匹配的位置分隔字符串。 > **Tip:** 如果你的模式匹配要求比這些還多,請考慮用 Perl 或 Tcl 寫一個用戶定義函數。 ## 9.7.1\. `LIKE` ``` _string_ LIKE _pattern_ [ESCAPE `_escape-character_`] _string_ NOT LIKE _pattern_ [ESCAPE `_escape-character_`] ``` 如果該`_string_`匹配提供的`_pattern_`, 那么`LIKE`表達式返回真。和我們想像的一樣,如果`LIKE` 返回真,那么`NOT LIKE`表達式將返回假,反之亦然。 一個等效的表達式是`NOT (``_string_` LIKE `_pattern_`)。 如果`_pattern_`不包含百分號或者下劃線,那么該模式只代表它本身; 這時候`LIKE`的行為就像等號操作符。在`_pattern_` 里的下劃線(`_`)匹配任何單個字符;而一個百分號(`%`) 匹配零或多個任何序列。 一些例子: ``` 'abc' LIKE 'abc' _true_ 'abc' LIKE 'a%' _true_ 'abc' LIKE '_b_' _true_ 'abc' LIKE 'c' _false_ ``` `LIKE`模式匹配總是覆蓋整個字符串。因此, 如果想要匹配在字符串內部任何位置的序列,該模式必須以百分號開頭和結尾。 要匹配下劃線或者百分號本身,在`_pattern_` 里相應的字符必須前導逃逸字符。缺省的逃逸字符是反斜杠, 但是你可以用`ESCAPE`子句指定一個。要匹配逃逸字符本身, 寫兩個逃逸字符。 > **Note:** 如果你關閉了[standard_conforming_strings](#calibre_link-1031)選項, 那么在文本字符串常量里的任意反斜杠都需要雙寫。 參閱[Section 4.1.2.1](#calibre_link-969)獲取更多信息。 我們也可以通過寫成`ESCAPE ''`的方式關閉逃逸機制, 這時,我們就不能關閉下劃線和百分號的特殊含義。 關鍵字`ILIKE`可以用于替換`LIKE`, 令該匹配就當前的區域設置是大小寫無關的。這個特性不是SQL標準, 是PostgreSQL擴展。 操作符`~~`等效于`LIKE`,而`~~*` 等效于`ILIKE`。還有`!~~`和`!~~*` 操作符分別代表`NOT LIKE`和`NOT ILIKE`。 所有這些操作符都是PostgreSQL特有的。 ## 9.7.2\. `SIMILAR TO` 正則表達式 ``` _string_ SIMILAR TO _pattern_ [ESCAPE `_escape-character_`] _string_ NOT SIMILAR TO _pattern_ [ESCAPE `_escape-character_`] ``` `SIMILAR TO`根據自己的模式是否匹配給定字符串而返回真或者假。 它和`LIKE`非常類似,只不過它使用 SQL 標準定義的正則表達式理解模式。 SQL 標準的正則表達式是在`LIKE` 表示法和普通的正則表達式表示法之間古怪的交叉。 類似`LIKE`,`SIMILAR TO` 操作符只有在它的模式匹配整個字符串的時候才能成功; 這一點和普通的正則表達式的行為不同,在普通的正則表達式里, 模式匹配字符串的任意部分。和`LIKE`類似的地方還有 `SIMILAR TO`使用`_`和`%` 分別匹配單個字符和任意字符串(這些和 POSIX 正則表達式里的`.` 和`.*`兼容)。 除了這些從`LIKE`借用的功能之外,`SIMILAR TO` 支持下面這些從 POSIX 正則表達式借用的模式匹配元字符: * `|`表示選擇(兩個候選之一) * `*`表示重復前面的項零次或更多次 * `+`表示重復前面的項一次或更多次 * `?`表示重復前面的項零次或一次 * `{``_m_``}`表示重復前面的項正好`_m_`次 * `{``_m_``,}`表示重復前面的項`_m_`或更多次 * `{``_m_``,``_n_``}` 表示重復前面的項至少`_m_`次,最多不超過`_n_`次 * Parentheses `()`把項組合成一個邏輯項 * `[...]` 聲明一個字符類,只在POSIX正則表達式中 請注意點(`.`)對于`SIMILAR TO`來說不是元字符。 和`LIKE`一樣,反斜杠關閉所有這些元字符的特殊含義; 當然我們也可以用`ESCAPE`聲明另外一個逃逸字符。 一些例子: ``` 'abc' SIMILAR TO 'abc' _true_ 'abc' SIMILAR TO 'a' _false_ 'abc' SIMILAR TO '%(b|d)%' _true_ 'abc' SIMILAR TO '(b|c)%' _false_ ``` 帶三個參數的`substring(`_string_` from `_pattern_` for `_escape-character_`)` 函數提供了一個從字符串中抽取一個匹配 SQL 正則表達式模式的子字符串功能。 和`SIMILAR TO`一樣,聲明的模式必須匹配整個字符串, 否則函數失效并返回 NULL 。為了標識在成功的時候應該返回的模式部分, 模式必須出現后跟雙引號(`"`)的兩個逃逸字符。 匹配這兩個標記之間的模式的字符串將被返回。 一些例子,以`#"`分隔返回的字符串: ``` substring('foobar' from '%#"o_b#"%' for '#') _oob_ substring('foobar' from '#"o_b#"%' for '#') _NULL_ ``` ## 9.7.3\. POSIX 正則表達式 [Table 9-11](#calibre_link-2191)列出了所有用于 POSIX 正則表達式的操作符。 **Table 9-11\. 正則表達式匹配操作符** | 操作符 | 描述 | 例子 | | --- | --- | --- | | `~` | 匹配正則表達式,大小寫相關 | `'thomas' ~ '.*thomas.*'` | | `~*` | 匹配正則表達式,大小寫無關 | `'thomas' ~* '.*Thomas.*'` | | `!~` | 不匹配正則表達式,大小寫相關 | `'thomas' !~ '.*Thomas.*'` | | `!~*` | 不匹配正則表達式,大小寫無關 | `'thomas' !~* '.*vadim.*'` | POSIX正則表達式提供了比`LIKE`和`SIMILAR TO` 操作符更強大的模式匹配的方法。許多 Unix 工具,比如`egrep`, `sed`,`awk`使用類似的模式匹配語言。 正則表達式是一個字符序列,它是定義一個字符串集合(一個_正則集合_ )的縮寫。如果一個字符串是正則表達式描述的正則集合中的一員時, 我們就說這個字符串匹配該正則表達式。和`LIKE`一樣, 模式字符準確地匹配字符串字符,除非在正則表達式語言里有特殊字符 (不過正則表達式用的特殊字符和`LIKE`用的不同)。 和`LIKE`不一樣的是,正則表達式可以匹配字符串里的任何位置, 除非該正則表達式明確地錨定在字符串的開頭或者結尾。 一些例子: ``` 'abc' ~ 'abc' _true_ 'abc' ~ '^a' _true_ 'abc' ~ '(b|d)' _true_ 'abc' ~ '^(b|c)' _false_ ``` POSIX模式語言將在下面詳細描述。 帶兩個參數的`substring(`_string_` from `_pattern_`)` 函數提供了從字符串中抽取一個匹配 POSIX 正則表達式模式的子字符串的方法。 如果沒有匹配它返回 NULL ,否則就是文本中匹配模式的那部分。 但是如果該模式包含任何圓括弧,那么將返回匹配第一對子表達式(對應第一個左圓括弧的)的文本。 如果你想在表達式里使用圓括弧而又不想導致這個例外, 那么你可以在整個表達式外邊放上一對圓括弧。如果你需要在想抽取的子表達式前有圓括弧, 參閱描述的非捕獲性圓括弧。 一些例子: ``` substring('foobar' from 'o.b') _oob_ substring('foobar' from 'o(.)b') _o_ ``` `regexp_replace`(`_source_`, `_pattern_`, `_replacement_` [, `_flags_` ])函數提供了將匹配 POSIX 正則表達式模式的子字符串替換為新文本的功能。如果沒有匹配 pattern 的子字符串, 那么返回不加修改的`_source_`字符串。如果有匹配, 則返回的 `_source_`字符串里面的對應子字符串將被`_replacement_` 字符串替換掉。`_replacement_`字符串可以包含`\``_n_`, 這里的`_n_`是 1 到 9 ,表明源字符串中匹配第`_n_` 個圓括弧子表達式的部分將插入在該位置,并且它可以包含`\&` 表示應該插入匹配整個模式的字符串。如果你需要放一個文本反斜杠在替換文本里, 那么寫`\\`。可選的`_flags_` 參數包含零個或多個改變函數行為的單字母標記。`i`表示進行大小寫無關的匹配, `g`表示替換每一個匹配的子字符串而不僅僅是第一個。其他支持的標記在 [Table 9-19](#calibre_link-2192)中描述。 一些例子: ``` regexp_replace('foobarbaz', 'b..', 'X') _fooXbaz_ regexp_replace('foobarbaz', 'b..', 'X', 'g') _fooXX_ regexp_replace('foobarbaz', 'b(..)', E'X\\1Y', 'g') _fooXarYXazY_ ``` `regexp_matches`(`_string_`, `_pattern_`[, `_flags_` ])函數返回一個從匹配POSIX正則表達式模式中獲取的所有子串結果的text數組。 這個函數可以返回零行,一行,或者多行(參閱下面的`g`標記)。如果`_pattern_` 沒有匹配,則函數返回零行。如果模式包含沒有括號的子表達式,則每行返回的是單元素的文本數組, 其中包含的子串相匹配整個模式。如果模式包含有括號的子表達式,函數返回一個文本數組,它的第 `_n_`個元素是子串匹配模式括號子表達式內的第`_n_`個元素。 (不計"非捕獲"的括號;詳細信息參閱下面)。參數`_flags_`是一個可選的text字符串, 含有0或者更多單字母標記來改變函數行為。標記`g`導致查找字符串中的每個匹配,而不僅是第一個, 每個匹配返回一行,其它支持的標記在[Table 9-19](#calibre_link-2192)里描述。 一些例子: ``` SELECT regexp_matches('foobarbequebaz', '(bar)(beque)'); regexp_matches ---------------- {bar,beque} (1 row) SELECT regexp_matches('foobarbequebazilbarfbonk', '(b[^b]+)(b[^b]+)', 'g'); regexp_matches ---------------- {bar,beque} {bazil,barf} (2 rows) SELECT regexp_matches('foobarbequebaz', 'barbeque'); regexp_matches ---------------- {barbeque} (1 row) ``` 使用select子句,可能強制`regexp_matches()`總是返回一行; 當你想要返回`SELECT`目標列表中的所有行,甚至沒有匹配的情況下,是有特別有用的。 ``` SELECT col1, (SELECT regexp_matches(col2, '(bar)(beque)')) FROM tab; ``` `regexp_split_to_table`(`_string_`, `_pattern_`[, `_flags_` ])函數使用POSIX正則表達式模式作為分隔符,分隔字符串。 如果沒有匹配`_pattern_`,函數將返回`_string_`。如果有至少一個匹配, 每個匹配返回從最后一個匹配結束(或者字符串的開頭)到匹配開始的文本。當沒有更多的匹配, 返回最后一個匹配的結束到字符串的結束的文本。`_flags_`參數是一個可選text字符串, 含有0或者更多單字母標記來改變函數行為。`regexp_split_to_table` 支持的標記在[Table 9-19](#calibre_link-2192)里描述。 除了`regexp_split_to_array`返回結果為text數組,`regexp_split_to_array` 函數行為與`regexp_split_to_table`相同,使用語法`regexp_split_to_array` (`_string_`, `_pattern_`[, `_flags_` ])。 參數與`regexp_split_to_table`相同。 一些例子: ``` SELECT foo FROM regexp_split_to_table('the quick brown fox jumps over the lazy dog', E'\\s+') AS foo; foo ------- the quick brown fox jumps over the lazy dog (9 rows) SELECT regexp_split_to_array('the quick brown fox jumps over the lazy dog', E'\\s+'); regexp_split_to_array ----------------------------------------------- {the,quick,brown,fox,jumps,over,the,lazy,dog} (1 row) SELECT foo FROM regexp_split_to_table('the quick brown fox', E'\\s*') AS foo; foo ----- t h e q u i c k b r o w n f o x (16 rows) ``` 作為最后一個例子表明,發生在字符串的開始或結束或緊接前一個的匹配,regexp分隔函數忽略零長度匹配, 這樣實現`regexp_matches`嚴格上來說是違背了的正則表達式匹配的定義,但在實際使用中, 通常是最便利的的行為。如Perl等軟件系統,使用了類似的定義。 ### 9.7.3.1\. 正則表達式細節 PostgreSQL的正則表達式使用 Henry Spencer 寫的一個包來實現。 下面的大部分描述都是從他的手冊頁里逐字拷貝過來的。 正則表達式(REs),在POSIX 1003.2中定義, 它有兩種形式:_擴展_ RE或ERE (基本上就是在`egrep`里的那些),_基本_RE 或BRE(基本上就是在`ed`里的那些)。PostgreSQL 兩種形式都實現了,并且還做了一些 POSIX 里面沒有的, 但是因為在類似 Perl 或者 Tcl 這樣的語言中得到廣泛應用的一些擴展。 使用了那些非 POSIX 擴展的正則表達式叫_高級_RE 或ARE。ARE 幾乎完全是 ERE 的超集,但是 BRE 有幾個符號上的不兼容(以及更多的限制)。 我們首先描述 ARE 和 ERE 形式,描述那些只適用于 ARE 的特性,然后描述與 BRE 的區別是什么。 > **Note:** PostgreSQL總是初始化一個遵循ARE規則的正則表達式。然而, 更多限制的ERE或BRE規則可以通過在RE模式前放置一個_embedded option_來選擇, 描述在[Section 9.7.3.4](#calibre_link-2193)。這對于期望完全兼容POSIX 1003.2規則的應用程序是有用的。 一個正則表達式定義為一個或多個_分支_, 由`|`分隔。它匹配其中任何一個分支的東西。 一個分支是零個或多個_有修飾的原子_或_約束_連接而成。 一個原子匹配第一個,后面的原子匹配第二個,以此類推;一個空分支匹配空字符串。 一個有修飾的原子是一個_原子_,后面可能跟著一個_量詞_。 沒有量詞的時候,它匹配一個原子,有量詞的時候,它可以匹配若干個原子。 _原子_可以是在[Table 9-12](#calibre_link-2194)里面顯示的任何可能。 可能的量詞和他們的含義在[Table 9-13](#calibre_link-2195)里顯示。 一個_約束_匹配一個空字符串,但只是在滿足特定條件下才匹配。 約束可以在能夠使用原子的地方使用,只是它不能跟著量詞。 最簡單的原子在[Table 9-14](#calibre_link-2196)里顯示;更多的約束稍后描述。 **Table 9-12\. 正則表達式原子** | 原子 | 描述 | | --- | --- | | `(``_re_``)` | (`_re_` 是任意正則表達式)匹配一個對`_re_` 的匹配,有可報告的匹配信息。 | | `(?:``_re_``)` | 同上,但是匹配不會被報告(一個"非捕獲"圓括弧),只在 ARE 中有。 | | `.` | 匹配任意單個字符 | | `[``_chars_``]` | 一個_方括弧表達式_,匹配任意的`_字符_` (參閱[Section 9.7.3.2](#calibre_link-2197)獲取更多細節) | | `\``_k_` | (`_k_`是非字母數字字符)匹配一個當作普通字符看待的特定字符, 比如`\\`匹配一個反斜杠。 | | `\``_c_` | `_c_`是一個字母數字(可能跟著其它字符),它是一個_逃逸_, 參閱[Section 9.7.3.3](#calibre_link-2198)。僅存在于 ARE 中;在 ERE 和 BRE 中, 它匹配`_c_`。 | | `{` | 如果后面跟著一個非數字字符,那么就匹配左花括弧`{`; 如果跟著一個數字,那么它是`_范圍_`的開始(見下面) | | `_x_` | 這里的`_x_`是一個沒有其它特征的單個字符,則匹配該字符 | RE不能以(`\`)結尾。 > **Note:** 如果關閉了[standard_conforming_strings](#calibre_link-1031), 任何文本字符串常量中的反斜杠都需要雙寫。參閱[Section 4.1.2.1](#calibre_link-969) 獲取更多信息。 **Table 9-13\. 正則表達式量詞** | 量詞 | 匹配 | | --- | --- | | `*` | 一個匹配 0 或者更多個原子的序列 | | `+` | 一個匹配 1 或者更多個原子的序列 | | `?` | 一個匹配 0 或者 1個原子的序列 | | `{``_m_``}` | 一個正好匹配`_m_`個原子的序列 | | `{``_m_``,}` | 一個匹配`_m_`個或者更多原子的序列 | | `{``_m_``,``_n_``}` | 一個匹配`_m_`到`_n_`個(包含兩端)原子的序列; `_m_`不能比`_n_`大 | | `*?` | `*`的非貪婪模式 | | `+?` | `+`的非貪婪模式 | | `??` | `?`的非貪婪模式 | | `{``_m_``}?` | `{``_m_``}`的非貪婪模式 | | `{``_m_``,}?` | `{``_m_``,}`的非貪婪模式 | | `{``_m_``,``_n_``}?` | `{``_m_``,``_n_``}`的非貪婪模式 | `{``_..._``}`的形式被稱作_范圍_。 一個范圍內的數字`_m_`和`_n_`都是無符號十進制整數, 允許的數值從 0 到 255 (閉區間)。 _非貪婪_的量詞(只在 ARE 中可用)匹配對應的正常(_貪婪_)模式, 區別是它尋找最少的匹配,而不是最多的匹配。參閱[Section 9.7.3.5](#calibre_link-2199) 獲取細節。 > **Note:** 一個量詞不能緊跟在另外一個量詞后面,例如,`**`是非法的。 量詞不能是表達式或者子表達式的開頭,也不能跟在`^` 或`|`后面。 **Table 9-14\. 正則表達式約束** | 約束 | 描述 | | --- | --- | | `^` | 匹配字符串的開頭 | | `$` | 匹配字符串的結尾 | | `(?=``_re_``)` | _正前瞻_匹配任何匹配`_re_` 的子字符串起始點(只在 ARE 中有) | | `(?!``_re_``)` | _負前瞻_匹配任何不匹配`_re_` 的子字符串起始點(只在 ARE 中有) | 前瞻約束不能包含_后引用_(參閱[Section 9.7.3.3](#calibre_link-2198)), 并且在其中的所有圓括弧都被認為是不捕獲的。 ### 9.7.3.2\. 方括弧表達式 _方括弧表達式_是一個包圍在`[]`里的字符列表。 它通常匹配任意單個列表中的字符(又見下文)。如果列表以`^`開頭, 它匹配任意單個(又見下文)_不在_該列表中的字符。如果該列表中兩個字符用 `-`隔開,那它就是那兩個字符(包括在內)之間的所有字符范圍的縮寫, 比如,在ASCII里`[0-9]`包含任何十進制數字。 兩個范圍共享一個終點是非法的,比如`a-c-e`。這個范圍與字符集關系密切, 可移植的程序不應該依靠它們。 想在列表中包含文本`]`,可以讓它做列表的首字符(如果用到了, 跟在`^` 后面)。想在列表中包含文本`-`, 可以讓它做列表的首字符或者末字符,或者一個范圍的第二個終點。 想在列表中把文本`-`當做范圍的起點,把它用`[.` 和`.]`包圍起來,這樣它就成為一個集合元素(見下文)。 除了這些字符本身,和一些用`[`的組合(見下段), 以及逃逸(只在 ARE 中有效)以外,所有其它特殊字符在方括弧表達式里都失去它們的特殊含義。 特別是,在 ERE 和 BRE 規則下`\`不是特殊的,但在 ARE 里, 它是特殊的(還是引入一個逃逸)。 在一個方括弧表達式里,一個集合元素(一個字符、一個當做一個字符的多字符序列、 或者一個表示上面兩種情況的集合序列)包含在`[.`和`.]` 里面的時候表示該集合元素的字符序列。該序列是該方括弧列表的一個元素。 這允許一個包含多字符集合元素的方括弧表達式就可以匹配多于一個字符,比如, 如果集合序列包含一個`ch`集合元素,那么`[[.ch.]]*c` 匹配`chchcc`的頭五個字符。譯注:其實把 [. 和 .] 括起來的整體當一個字符看就行了。 > **Note:** PostgreSQL目前不支持多字符集合元素。這些信息描述了將來可能有的行為。 在方括弧表達式里,在`[=`和`=]` 里包圍的集合元素是一個_等效表_,代表等于這里所有集合元素的字符序列, 包括它本身(如果沒有其它等效集合元素,那么就好像封裝元素是`[.` 和`.]`)。比如,如果`o`和`^` 是一個等效表的成員,那么`[[=o=]]`,`[[=^=]]`, `[o^]`都是同義的。一個等效表不能是一個范圍的端點。 在方括弧表達式里,在`[:`和`:]` 里面封裝的字符表名字代表屬于該表的所有字符的列表。標準的字符表名字是: `alnum`, `alpha`, `blank`, `cntrl`, `digit`, `graph`, `lower`, `print`, `punct`, `space`, `upper`, `xdigit`。 它們代表在ctype 里定義的字符表。本地化設置可能會提供其它的表。字符表不能用做一個范圍的端點。 在方括弧表達式里有兩個特例:方括弧表達式`[[:&lt;:]]`和 `[[:&gt;:]]`是約束,分別匹配一個單詞開頭和結束的空串。 單詞定義為一個單詞字符序列,前面和后面都沒有其它單詞字符。 單詞字符是一個`alnum`字符(和ctype 里定義的一樣)或者一個下劃線。這是一個擴展,兼容POSIX 1003.2 , 但那里面并沒有說明,而且在準備移植到其它系統里去的軟件里一定要小心使用。 通常下面描述的約束逃逸更好些;他們并非更標準,但是更容易輸入。 ### 9.7.3.3\. 正則表達式逃逸 _逃逸_是以`\`開頭,后面跟著一個字母數字字符的特殊序列。 逃逸有好幾種變體:字符項、表縮寫、約束逃逸、后引用。在 ARE 里,如果一個`\` 后面跟著一個字母數字,但是并未組成一個合法的逃逸,那么它是非法的。在 ERE 里則沒有逃逸: 在方括弧表達式之外,一個跟著字母數字字符的`\`只是表示該字符是一個普通的字符, 而在一個方括弧表達式里,`\`是一個普通的字符(后者實際上是 ERE 和 ARE 之間的不兼容)。 _字符項逃逸_用于方便我們聲明正則表達式里那些不可打印的字符。 它們在[Table 9-15](#calibre_link-2200)里列出。 _類縮寫逃逸_用來提供一些常用的字符類縮寫。 他們在[Table 9-16](#calibre_link-2201)里列出。 _約束逃逸_是一個約束,如果滿足特定的條件,它匹配該空字符串,以逃逸形式寫出。 它們在[Table 9-17](#calibre_link-2202)里列出。 _后引用_(`\``_n_`)匹配數字`_n_` 指定的前面的圓括弧子表達式匹配的同一個字符串(參閱[Table 9-18](#calibre_link-2203))。 比如,`([bc])\1`匹配`bb`或`cc`但是不匹配`bc`或`cb`。 正則表達式里的子表達式必須完全在后引用前面。子表達式以它的括號的順序排序。 非捕獲圓括弧并不定義子表達式。 > **Note:** 請注意,如果把模式當作一個 SQL 字符串常量輸入,那么逃逸前導的`\`需要雙倍地寫: > > ``` > '123' ~ E'^\\d{3}' _true_ > ``` **Table 9-15\. 正則表達式字符項逃逸** | 逃逸 | 描述 | | --- | --- | | `\a` | 警笛(鈴聲)字符,和 C 里一樣 | | `\b` | 退格,和 C 里一樣 | | `\B` | `\`的同義詞,用于減少反斜杠加倍的需要 | | `\c``_X_` | (這里`_X_`是任意字符)字符的低 5 位和`_X_` 里的相同,其它位都是 0 | | `\e` | 集合序列名字是`ESC`的字符,如果不是, 則是八進制值為 033 的字符 | | `\f` | 進紙,和 C 里一樣 | | `\n` | 新行,和 C 里一樣 | | `\r` | 回車,和 C 里一樣 | | `\t` | 水平制表符,和 C 里一樣 | | `\u``_wxyz_` | (這里的`_wxyz_`是恰好四位十六進制位)本機字節序的 UTF-16 字符 `U+``_wxyz_` | | `\U``_stuvwxyz_` | (這里的`_stuvwxyz_`是恰好八位十六進制位) 為假想中的 Unicode 32 位擴展保留的 | | `\v` | 垂直制表符,和 C 里一樣 | | `\x``_hhh_` | (這里的`_hhh_`是一個十六進制序列)十六進制值為 `0x``_hhh_`的字符(不管用了幾個十六進制位, 都是一個字符) | | `\0` | 值為`0`的字符 (null 字節) | | `\``_xy_` | (這里的`_xy_`是恰好兩個八進制位, 并且不是一個_后引用_)八進制值為`0``_xy_` 的字符 | | `\``_xyz_` | (這里的`_xyz_`是恰好三位八進制位, 并且不是一個_后引用_)八進制值為`0``_xyz_` 的字符 | 十六進制位是`0`-`9`, `a`-`f`, `A`-`F`。八進制位是`0`-`7`。 字符項逃逸總是被當作普通字符。比如,`\135`是 ASCII 中的`]`, 但`\135`并不終止一個方括弧表達式。 **Table 9-16\. 正則表達式類縮寫逃逸** | 逃逸 | 描述 | | --- | --- | | `\d` | `[[:digit:]]` | | `\s` | `[[:space:]]` | | `\w` | `[[:alnum:]_]` (注意,這里是包含下劃線的) | | `\D` | `[^[:digit:]]` | | `\S` | `[^[:space:]]` | | `\W` | `[^[:alnum:]_]` (注意,這里是包含下劃線的) | 在方括弧表達式里,`\d`, `\s`, `\w` 會失去他們的外層方括弧,而 `\D`, `\S`, `\W` 是非法的。比如`[a-c\d]`等效于`[a-c[:digit:]]`。 同樣`[a-c\D]`原來等效于`[a-c^[:digit:]]`的,也是非法的。 **Table 9-17\. 正則表達式約束逃逸** | 逃逸 | 描述 | | --- | --- | | `\A` | 只匹配字符串開頭(參閱[Section 9.7.3.5](#calibre_link-2199) 獲取它和`^`區別的信息) | | `\m` | 只匹配一個詞的開頭 | | `\M` | 只匹配一個詞的結尾 | | `\y` | 只匹配一個詞的開頭或者結尾 | | `\Y` | 只匹配那些既不是詞的開頭也不是詞的結尾的點 | | `\Z` | 只匹配一個字符串的結尾(參閱[Section 9.7.3.5](#calibre_link-2199) 獲取它和`$`區別的信息) | 一個詞的定義是上面`[[:&lt;:]]`和`[[:&gt;:]]`的聲明。 在方括弧表達式里,約束逃逸是非法的。 **Table 9-18\. 正則表達式后引用** | 逃逸 | 描述 | | --- | --- | | `\``_m_` | (這里的`_m_`是一個非零十進制位) 一個指向第`_m_`個子表達式的后引用 | | `\``_mnn_` | (這里的`_m_`是一個非零十進制位,`_nn_` 是更多的十進制位,并且十進制數值`_mnn_` 不能大于到這個位置為止的閉合捕獲圓括弧的個數)一個指向第`_mnn_` 個子表達式的后引用 | > **Note:** 在八進制字符項逃逸和后引用之間有一個繼承的歧義存在,這個歧義是通過跟著的啟發分析解決的, 像上面描述的那樣。前導零總是表示這是一個八進制逃逸。而單個非零數字, 如果沒有跟著任何其它數字,那么總是認為是后引用。 一個多數據位的非零開頭的序列也認為是后引用(只要它在合適的子表達式后面, 也就是說,數值在后引用的合法范圍內),否則就認為是一個八進制。 ### 9.7.3.4\. 正則表達式元語法 除了上面描述的主要語法之外,還有幾種特殊形式和雜項語法。 正則表達式可以以兩個特殊的_指示器_前綴之一開始: 如果一個正則表達式以`***:`開頭,那么剩下的正則表達式都被當作 ARE 。 (這在PostgreSQL中通常沒有影響,因為正則表達式被假設為ARE; 但是如果ERE或BRE模式被`_flags_`參數指定為正則表達式函數時是有影響的。) 如果一個的正則表達式以`***=`開頭,那么剩下的正則表達式被當作一個文本串, 所有的字符都被認為是一個普通字符。 一個 ARE 可以以_嵌入選項_開頭:一個`(?``_xyz_``)` 序列(這里的`_xyz_`是一個或多個字母字符)聲明影響剩余正則表達式的選項。 這些選項覆蓋任何前面判斷的選項—它們可以重寫正則表達式操作符隱含的大小寫敏感性, 或者正則表達式函數的`_flags_`參數。可用的選項字母在 [Table 9-19](#calibre_link-2192)顯示。請注意, 正則表達式函數的`_flags_`參數使用相同的選項字母。 **Table 9-19\. ARE 嵌入選項字母** | 選項 | 描述 | | --- | --- | | `b` | 剩余的正則表達式是 BRE | | `c` | 大小寫敏感匹配(覆蓋操作符類型) | | `e` | 剩余的正則表達式是 ERE | | `i` | 大小寫不敏感匹配(參閱[Section 9.7.3.5](#calibre_link-2199))(覆蓋操作符類型) | | `m` | `n`的歷史同義詞 | | `n` | 新行敏感匹配(參閱[Section 9.7.3.5](#calibre_link-2199)) | | `p` | 部分新行敏感匹配(參閱[Section 9.7.3.5](#calibre_link-2199)) | | `q` | 重置正則表達式為一個文本("引起")字符串,所有都是普通字符。 | | `s` | 非新行敏感匹配(缺省) | | `t` | 緊語法(缺省,見下文) | | `w` | 反轉部分新行敏感("怪異")匹配(參閱[Section 9.7.3.5](#calibre_link-2199)) | | `x` | 擴展的語法(見下文) | 嵌入的選項在終止其序列的`)`發生作用。他們只在 ARE 的開始處起作用(如果有, 則在任何`***:`指示器后面)。 除了通常的(_緊_)正則表達式語法(這種情況下所有字符都重要), 還有一種_擴展_語法,可以通過聲明嵌入的`x`選項獲得。 在擴展語法里,正則表達式中的空白字符被忽略,就像那些在`#` 和新行之間的字符一樣(或正則表達式的結尾)。 這樣就允許我們給一個復雜的正則表達式分段和注釋。不過這個基本規則上有三種例外: * 前置了`\`的空白字符或者 `#`保留 * 方括弧里的空白或者`#`保留 * 在多字符符號里面不能出現空白和注釋,比如`(?:` 在這里,空白是空格、水平制表符、新行、和任何屬于`_space_`(空白)字符表的字符。 最后,在 ARE 里,方括弧表達式外面,序列`(?#``_ttt_``)` (這里的`_ttt_`是任意不包含`)`的文本)是一個注釋,完全被忽略。 同樣,這樣的東西是不允許出現在多字符符號的字符中間的,比如`(?:`。 這樣的注釋是比有用的機制的更久遠的歷史造成的,他們的用法已經廢棄了; 我們應該使用擴展語法代替他。 如果聲明了一個初始化的`***=`指示器,那么所有這些元語法擴展都 _不能_使用,因為這樣表示把用戶輸入當作一個文本字符串而不是正則表達式對待。 ### 9.7.3.5\. 正則表達式匹配規則 在正則表達式可以匹配給出的字符串中多于一個子字符串的情況下, 正則表達式匹配字符串中最靠前的那個子字符串。 如果正則表達式可以匹配在那個位置開始的多個子字符串,要么是取最長的子字符串, 要么是最短的,具體哪種,取決于正則表達式是_貪婪_的還是 _非貪婪_的。 一個正則表達式是否貪婪取決于下面規則: * 大多數原子,以及所有約束,都沒有貪婪屬性(因為它們畢竟無法匹配個數變化的文本)。 * 在一個正則表達式周圍加上圓括弧并不會改變其貪婪性。 * 一個帶一個固定重復次數的量詞(`{``_m_``}` 或`{``_m_``}?`) 量化的原子和原子自身有著同樣的貪婪性(可能是沒有)。 * 一個帶其它普通的量詞(包括`{``_m_``,``_n_``}` 中`_m_`等于`_n_`的情況)量化的原子是貪婪的(首選最長匹配)。 * 一個帶非貪婪量詞(包括`{``_m_``,``_n_``}?` 中`_m_`等于`_n_`的情況)量化原子是非貪婪的(首選最短匹配)。 * 一個分支(也就是一個沒有頂級`|`操作的正則表達式) 和它里面的第一個有貪婪屬性的量化原子有著同樣的貪婪性。 * 一個由`|`操作符連接起來的兩個或者更多分支組成的正則表達式總是貪婪的。 上面的規則所描述的貪婪屬性不僅僅適用于獨立的量化原子, 而且也適用于包含量化原子的分支和整個正則表達式。這里的意思是, 匹配是按照分支或者整個正則表達式_作為一個整體_ 匹配最長或者最短的子字符串的可能。一旦整個匹配的長度確定, 那么匹配任意子表達式的部分就基于該子表達式的貪婪屬性進行判斷, 在正則表達式里面靠前的子表達式的優先級高于靠后的子表達式。 一個表達這些的例子: ``` SELECT SUBSTRING('XY1234Z', 'Y*([0-9]{1,3})'); _Result:_ <samp class="literal">123</samp> SELECT SUBSTRING('XY1234Z', 'Y*?([0-9]{1,3})'); _Result:_ <samp class="literal">1</samp> ``` 在第一個例子里,正則表達式作為整體是貪婪的,因為`Y*`是貪婪的。 它可以匹配從`Y`開始的東西,并且它匹配從這個位置開始的最長的字符串, 也就是`Y123`。輸出是這里的圓括弧包圍的部分,或者說是`123`。 在第二個例子里,正則表達式總體上是一個非貪婪的正則表達式 ,因為`Y*?` 是非貪婪的。它可以匹配從`Y`開始的最短的子字符串,也就是說`Y1`。 子表達式`[0-9]{1,3}`是貪婪的,但是它不能修改總體匹配長度的決定; 因此它被迫只匹配`1`。 簡單說,如果一個正則表達式同時包含貪婪和非貪婪的子表達式, 那么總匹配長度要么是最長可能,要么是最短可能,取決于給整個正則表達式賦予的貪婪屬性。 給子表達式賦予的貪婪屬性只影響在這個匹配里,各個子表達式之間相互允許 "吃進"的多少。 量詞`{1,1}`和`{1,1}?` 可以分別用于在一個子表達式或者整個正則表達式上強制貪婪或者非貪婪。 匹配長度是以字符衡量的,而不是集合的元素。一個空字符串會被認為比什么都不匹配長。 比如:`bb*`匹配`abbbc`的中間三個字符; `(week|wee)(night|knights)`匹配`weeknights`的所有十個字符; 而`(.*).*`匹配`abc`的時候,圓括弧包圍的子表達式匹配所有三個字符; 而如果用`(a*)*`匹配`bc`,那么正則表達式和圓括弧子表達式都匹配空字符串。 如果聲明了大小寫無關的匹配,那么效果就好像把所有字母上的大小寫區別取消了一樣。 如果一個存在大小寫差別的字母以一個普通字符的形式出現在方括弧表達式外面, 那么它實際上被轉換成一個包含大小寫的方括弧表達式,也就是說,`x` 變成`[xX]`。如果它出現在一個方括弧表達式里面, 那么它的所有大小寫的同族都被加入方括弧表達式中,也就是說,`[x]` 變成`[xX]`而`[^x]`變成 `[^xX]`。 如果聲明了新行敏感匹配,`.`和使用`^` 的方括弧表達式將永遠不會匹配新行字符(這樣,匹配就絕對不會跨新行, 除非正則表達式明確地安排了這樣的情況)并且`^`和`$` 除了分別匹配字符串開頭和結尾之外,還將分別匹配新行后面和前面的空字符串。 但是 ARE 逃逸`\A`和`\Z` 仍然_只_匹配字符串的開頭和結尾。 如果聲明了部分新行敏感匹配,那么它影響`.`和方括弧表達式, 這個時候和新行敏感匹配一樣,但是不影響`^`和`$`。 如果聲明了反轉部分新行敏感匹配,那么它影響`^`和`$`, 作用和新行敏感匹配里一樣,但是不影響`.`和方括弧表達式。 這個沒什么太多用途,只是為了對稱提供的。 ### 9.7.3.6\. 限制和兼容性 在這個實現里,對正則表達式的長度沒有特別的限制,但是, 那些希望能夠有很好移植行的程序應該避免寫超過 256 字節的正則表達式 , 因為 POSIX 兼容的實現可以拒絕接受這樣的正則表達式。 ARE 實際上和 POSIX ERE 不兼容的唯一的特性是在方括弧表達式里`\` 并不失去它特殊的含義。所有其它 ARE 特性都使用在 POSIX ERE 里面是非法或者是未定義、 未聲明效果的語法;指示器的`***`就是在 POSIX 的 BRE 和 ERE 之外的語法。 許多 ARE 擴展都是從 Perl 那里借來的,但是有些我做了修改,清理了一下, 以及一些 Perl 里沒有出現的擴展。要注意的不兼容包括`\b`, `\B`, 對結尾的新行缺乏特別的處理,對那些新行敏感匹配的附加的補齊方括弧表達式, 在前瞻約束里對圓括弧和方括弧引用的限制,以及最長/最短匹配(而不是第一匹配)語義。 PostgreSQL 7.4 之前的版本里的 ARE 和 ERE 存在兩個非常顯著的不兼容: * 在 ARE 里,后面跟著一個字母數字的`\`要么是一個逃逸,要么是錯誤, 但是在以前的版本里,它只是寫那個字母數字的另外一種方法。這個應該不是什么問題, 因為在以前的版本里沒有什么原因讓我們寫這樣的序列。 * 在 ARE 里,`\`在`[]`里還是一個特殊字符, 因此在方括弧表達式里的一個文本`\`必須寫成`\\`。 ### 9.7.3.7\. 基本正則表達式 BRE 在幾個方面和 ERE 不太一樣。在BRE里,`|`, `+`,`?` 都是普通字符,它們沒有等效的功能替換。范圍的分隔符是`\{`和`\}`, 因為`{`和`}`本身是普通字符。嵌套的子表達式的圓括弧是`\(` 和`\)`,因為`(`和`)`自身是普通字符。 除非在正則表達式開頭或者是圓括弧封裝的子表達式開頭,`^`都是普通字符, 除非在正則表達式結尾或者是圓括弧封裝的子表達式的結尾,`$`是一個普通字符, 而如果`*`出現在正則表達式開頭或者是圓括弧封裝的子表達式開頭 (前面可能有`^`),那么它是個普通字符。最后,可以用單數字的后引用, 以及`\&lt;`和`\&gt;`分別是`[[:&lt;:]]`和`[[:&gt;:]]` 的同義詞;在BRE里沒有其它的逃逸。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看