第五章 瘋狂Caché 運算符和表達式(四)

第五章 瘋狂Caché 運算符和表達式(四)

模式匹配

Caché支持兩種模式匹配系統:

  • 這裏描述的Caché模式匹配是一種用問號()分隔模式字符串開頭的語法。或(‘?)。
  • 正則表達式,許多軟件供應商支持的模式匹配語法。正則表達式可以與$LOCATE$MATCH函數以及%Regex.Matcher類的方法一起使用。

這些模式匹配系統是完全獨立的,不能組合。

Caché Pattern Match運算符測試其左操作數中的字符是否由右操作數中的模式正確指定。它返回一個布爾值。當模式正確指定左操作數中的字符模式時,模式匹配運算符會產生TRUE(1)結果。如果模式沒有正確指定左操作數中的字符模式,則生成FALSE(0)結果。

例如,以下測試字符串SSN是否包含有效的美國社會保險號(3位、連字符、2位、連字符和4位):

 SET ssn="123-45-6789"
 SET match = ssn    ?3N1"-"2N1"-"4N
 WRITE match
1

左操作數(測試值)和右操作數(模式)可以用一個或多個空格分隔,也可以不用空格分隔,如以下等效程序示例所示:

 SET ssn="123-45-6789"
 SET match = ssn?3N1"-"2N1"-"4N
 WRITE match
1

操作符後面不允許有空格。模式中的空格必須在帶引號的字符串內,並被解釋爲模式的一部分。

模式匹配操作的一般格式如下:

operand?pattern
  • operand 計算結果爲字符串或數字的表達式,要測試其字符是否具有模式。
  • pattern 以字符開頭的模式匹配序列。(或與‘?用於不匹配測試)。模式序列可以是以下之一:一個或多個模式元素的序列;計算爲一個或多個模式元素的序列的間接引用

模式元素由以下內容之一組成:

  • 重複匹配代碼repeat-count pattern-codes
  • 重複字符串repeat-count literal-string
  • 重複替換repeat-count alternation
名稱 描述
repeat-count 重複計數-要匹配的確切實例數。重複計數的計算結果可以是整數或句點通配符(.)。使用句點指定任意數量的實例。
pattern-codes 一個或多個模式代碼。如果指定了多個代碼,則通過匹配任何一個代碼來滿足該模式。
literal-string 用雙引號括起來的文字字符串。
alternation 一組可供選擇的模式元素序列(以便對操作數字符串的一段執行模式匹配)。這在模式規範中提供了邏輯OR功能。

如果要匹配特定的一個或多個字符,請在模式中使用雙引號括起來的文字字符串。在其他情況下,請使用CachéObjectScript提供的特殊模式代碼。與特定模式代碼相關聯的字符(在某種程度上)依賴於區域設置。下表顯示了可用的模式代碼及其含義:

代碼 含義
A 匹配任何大寫或小寫字母字符。區域設置的8位字符集定義了什麼是字母字符。對於英語區域設置(基於拉丁文-1字符集),這包括ASCII值65到90(A到Z)、97到122(a到z)、170、181、186、192到214、216到246和248到255。
C 匹配任何ASCII控制字符(ASCII值0到31和擴展ASCII值127到159)。
E 匹配任何字符,包括非打印字符、空格字符和控制字符。
L 匹配任何小寫字母字符。區域設置的8位字符集定義了什麼是小寫字符。對於英語區域設置(基於拉丁文-1字符集),這包括ASCII值97到122(a到z)、170、181、186、223到246和248到255。
N 匹配10個數字字符0到9(ASCII 48到57)中的任何一個。
P 匹配任何標點符號。區域設置的字符集定義擴展(8位)ASCII字符集的標點符號。對於英語區域設置(基於拉丁文-1字符集),這包括ASCII值32到47、58到64、91到96、123到126、160到169、171到177、180、182到184、187、191、215和247。
U 匹配任何大寫字母字符。區域設置的8位字符集定義了什麼是大寫字符。對於英語區域設置(基於拉丁文-1字符集),這包括ASCII值65到90(A到Z)、192到214和216到222。
R,B,M 匹配西里爾8位字母字符映射。R匹配任何西里爾字符(ASCII值192到255)。B匹配大寫西里爾字符(ASCII值192到223)。M匹配小寫西里爾字符(ASCII值爲224到255)。這些模式代碼僅在俄語8位Windows區域設置(Ruw8)中有意義。在其他地區,它們可以成功執行,但無法匹配任何字符。
ZFWCHARZ 匹配日語ZENKAKU字符集中的任何字符。ZFWCHARZ匹配全角字符,例如漢字範圍中的字符,以及在某些終端仿真器顯示時佔用雙倍單元格的許多非漢字字符。ZFWCHARZ還匹配JIS2004標準中定義的303個代理項對字符,將每個代理項對視爲單個字符。例如,代理項對字符$WC(131083)?1ZFWCHARZ匹配。此模式匹配代碼需要日語區域設置。
ZHWKATAZ 匹配日文漢字假名字符集中的任何字符。這些是Unicode值65377(FF61)到65439(FF9F)。此模式匹配代碼需要日語區域設置。

模式代碼不區分大小寫;可以用大寫或小寫指定它們。例如,?5N等同於?5n。可以指定多個模式代碼以匹配特定字符或字符串。例如,?1NU匹配數字或大寫字母。

正如Caché術語表中所述,ASCII字符集是指擴展的8位字符集,而不是更有限的7位字符集。

注意:使用雙引號字符的模式匹配可能會產生不一致的結果,特別是當數據是從使用不同NLS區域設置的Caché實現提供的時候。直雙引號字符($CHAR(34)=“)匹配爲標點符號。方向雙引號字符(大引號)與標點符號字符不匹配。8位定向雙引號字符($CHAR(147)= “$CHAR(148)=”)作爲控制字符匹配。Unicode定向雙引號字符($CHAR(8220)=“$CHAR(8221)=”)作爲標點符號或控制字符不匹配。

模式匹配運算符與二元包含([)運算符不同。即使只有左操作數的子字符串與右操作數匹配,二進制CONTAINS運算符也會返回TRUE(1)。此外,BINARY CONTAINS表達式不提供模式匹配運算符提供的選項範圍。在BINARY CONTAINS表達式中,只能使用單個字符串作爲右操作數,沒有任何特殊代碼。

例如,假設變量var2包含值“abc”。模式匹配表達式:

 SET match = var2?2L

這會將Match設置爲false(0),因爲var2包含三個小寫字符,而不僅僅是兩個。

以下是一些基本模式匹配的示例:

/// d ##class(PHA.TEST.ObjectScript).TestPatternMatch()
ClassMethod TestPatternMatch(params)
{
 SET var = "O"
 WRITE "是字母O",!

 WRITE "...字母字符? "
 WRITE var?1A,!

 WRITE "...數字字符? "
 WRITE var?1N,!

 WRITE "...是字母或 ",!,"  是數字? "
 WRITE var?1AN,!

 WRITE "...是字母或 ",!," A Zenkaku漢字字符? "
 WRITE var?1AZFWCHARZ,!

 WRITE "...是數字或 ",!,"  漢字假名字符? "
 WRITE var?1ZHWKATAZN
}
DHC-APP>w ##class(PHA.TEST.ObjectScript).TestPatternMatch()
是字母O
...字母字符? 1
...數字字符? 0
...是字母或
  是數字? 1
...是字母或
 A Zenkaku漢字字符? 1
...是數字或
  漢字假名字符? 0

可以通過指定以下內容來擴展模式代碼的範圍:

指定模式可以出現的次數

要定義模式可在目標操作數中出現的次數範圍,請使用以下格式:

n.n

第一個n定義出現範圍的下限;第二個n定義上限。

例如,假設變量var3包含字符串“ABABAB”。在下面的表達式中,1.4表示識別出1到4次“AB”

SET match = var3?1.4"AB"

即使var3只包含三次出現的“AB”,表達式也會返回TRUE(1)結果。

作爲另一個示例,請考慮以下表達式:

SET match = var3?1.6A

此表達式檢查var3是否包含1到6個字母字符。下面的表達式:只有當var3包含零個或六個以上字符時,才返回FALSE(0)結果。

如果省略任一n,則CachéObjectScript將提供默認值。第一個n的默認值爲零(0)。第二個n的默認值是任何數字。考慮以下示例:

 SET match = var3?1."AB"

只要var3至少包含模式字符串“AB”的一個匹配項,此示例就會返回TRUE(1)結果。

指定多個模式

要定義多個模式,可以將n和Pattern組合成任意長度的序列。考慮以下示例:

SET match = date?2N1"/"2N1"/"2N

此表達式檢查格式爲mm/dd/yy的日期值。以任意長度的順序排列的圖案。考慮以下示例:字符串“4/27/98”將返回FALSE,因爲月份只有一個數字。要同時檢測一位數和兩位數月份,可以將表達式修改爲:

SET match = date?1.2N1"/"2N1"/"2N

現在,第一個模式匹配(1.2N)接受1或2個數字。它使用可選句點(.)。要定義上一節中描述的可接受事件範圍,請執行以下操作。

指定組合模式

要定義組合模式,請使用以下表單:

Pattern1Pattern2

使用組合模式時,將對照目標操作數檢查由pattern1後跟pattern2組成的序列。例如,考慮以下表達式:

 SET match = value?3N.4L

此表達式檢查三個數字後跟零到四個小寫字母字符的模式。僅當目標操作數正好包含組合模式的一個匹配項時,表達式才返回TRUE(1)。例如,字符串“345g”“345gfij”將符合條件,但“345gfijhkbc”``“345gfij276hkbc”不符合條件。

DHC-APP>w "345g"?3N.4L
1
DHC-APP>w "345"?3N.4L
1

指定不確定模式

要定義不確定模式,請使用以下形式:

.pattern

對於不確定模式,將檢查目標操作數是否出現模式,但接受任意數量的出現(包括零出現)。例如,請考慮以下表達式:

SET match = value?.N

如果目標操作數包含零個、一個或多個數字字符,並且不包含任何其他類型的字符,則此表達式返回TRUE(1)

DHC-APP>w "A"?.U
1
DHC-APP>w "Aa"?.U
0

指定交替模式(邏輯或)

交替允許測試操作數是否與一組指定模式序列中的一個或多個匹配。它爲模式匹配提供了邏輯或功能。

替換具有以下語法:

( pattern-element sequence {, pattern-element sequence }...)

因此,如果val包含字母“A”的一個匹配項或字母“B”的一個匹配項,則以下模式返回TRUE(1)

 SET match = value?1(1"A",1"B")

可以具有嵌套的替換模式,如以下模式匹配表達式所示:

 SET match = value?.(.(1A,1N),1P)

例如,可能想要驗證一個美國電話號碼。電話號碼至少必須是用連字符(-)分隔第三位和第四位的7位電話號碼。例如:

nnn-nnnn

電話號碼還可以包括三位數的區號,該區號必須用圓括號括起來,或者用連字符與號碼的其餘部分隔開。例如:

(nnn) nnn-nnnn
nnn-nnn-nnnn

以下模式匹配表達式描述了美國電話號碼的三種有效形式:

 SET match = phone?3N1"-"4N
 SET match = phone?3N1"-"3N1"-"4N
 SET match = phone?1"("3N1") "3N1"-"4N

如果沒有替換,將需要以下複合布爾表達式來驗證任何形式的美國電話號碼。

  SET match = 
     (
     (phone?3N1"-"4N) || 
     (phone?3N1"-"3N1"-"4N) || 
     (phone?1"("3N1") "3N1"-"4N)
     )

通過替換,以下單一模式可以驗證任何形式的美國電話號碼:

 SET match = phone?.1(1"("3N1") ",3N1"-")3N1"-"4N

本例中的交替允許電話號碼的區號分量由1"("3N1") "3N1"-"滿足。交替計數範圍0到1表示操作數電話可以有0或1區號分量。

重複計數大於一(1)的交替可以產生許多可接受模式的組合。以下替換與顯示的字符串匹配,並與其他26個三字符串匹配

DHC-APP>w "CAT"?3(1"C",1"A",1"T")
1
DHC-APP>w "CAT"?3(1"C",1"A",2"T")
0
DHC-APP>w "CATT"?3(1"C",1"A",2"T")
1

使用不完整的模式

如果模式匹配成功地僅描述了字符串的一部分,則模式匹配將返回FALSE(0)結果。也就是說,當模式完成時不能有任何剩餘的字符串。以下表達式的計算結果爲FALSE(0),因爲該模式與最後的“R”不匹配:

DHC-APP>w "RAW BAR"?.U1P2U
0
DHC-APP>w "RAW BAR"?.U1P3U
1
DHC-APP>w "RAW BAR"?.U1P4U
0

解釋多重模式

當模式與操作數匹配時,可以有多個模式解釋。例如,可以用兩種方式解釋以下表達式:

DHC-APP>w "/////A#####B$$$$$"?.E1U.E
1
  1. 第一個“.E”匹配子字符串“/////”1U匹配“A”,第二個“.E”匹配子字符串“#####B$$$$$”
  2. 第一個“.E”匹配子字符串“/////A#####”1U匹配字符“B”,第二個“.E”匹配子字符串“$$$$$”

只要表達式的至少一個解釋爲TRUE(1),則該表達式的值爲TRUE。

不匹配運算符

可以通過將一元NOT運算符()與模式匹配一起使用來生成不匹配操作:

operand'?pattern

Not Match反轉模式匹配的真值。如果操作數中的字符不能由模式描述,則NOT MATCH返回結果TRUE(1)。如果模式與操作數中的所有字符匹配,則NOT MATCH返回FALSE(0)結果。

下面的示例使用不匹配運算符:

  WRITE !,"abc" ?3L
  WRITE !,"abc" '?3L
  WRITE !,"abc" ?3N
  WRITE !,"abc" '?3N
  WRITE !,"abc" '?3E
1
0
0
1
0
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章