在計算機科學中，模式匹配是檢查給定記號序列中，是否存在某種模式的組成部分的行為。與模式識別相反，匹配通常必須是精確的。模式通常具有序列或樹狀結構的形式。模式匹配的用途包括：輸出一個模式在一個記號序列中的位置（如果有的話），輸出匹配模式的一些組成部份，以及用一些其他的記號序列替換匹配模式（即搜尋和替換）。 概述 在一些程式語言中，模式被用作一種通用工具，基於資料的結構來處理資料，包括 C、 F、Haskell、ML、Python、Ruby、Rust、Scala、Swift 和 Mathematica 的符號式 Wolfram 語言，它們擁有表達樹狀結構的特殊語法，和基於它的條件執行和值檢索的。 經常可以給出逐個嘗試的式模式，它產生強力的條件程式設計構造。模式匹配有時包括對守衛子句的支援。 字元序列也就是字串，經常使用正則表示式來描述，並使用像回溯這樣的技術來進行匹配。解析演算法經常依賴模式匹配來將字串變換成語法樹 Warth Alessandro and Ian Piumarta OMeta an objectoriented language for pattern matching Proceedings of the 2007 symposium on Dynamic languages ACM 2007Knuth Donald E James H Morris Jr and Vaughan R Pratt Fast pattern matching in strings SIAM journal on computing 62 1977 323350。 歷史 具有模式匹配構造的早期程式語言包括：COMIT（1957 年）、SNOBOL（1962 年）、具有樹狀模式的（1968 年）、Prolog（1972 年）、SASL（1976 年）、NPL（1977 年）和 KRC（1981 年）。 很多文字編輯器支援各種的模式匹配：支援正則表示式查詢的，和在查詢中支援 OR 運算的某些版本的。計算機代數系統一般支援在代數表示式上的模式匹配 Joel Moses Symbolic Integration MIT Project MAC MACTR47 December 1967。 簡單模式 在模式匹配中，最簡單的模式是一個明確的值或一個變數。例如，考慮採用 Haskell 語法的一個簡單函式，這裡函式引數不放在圓括號內但用空白分隔， 不是賦值而是定義： f 0 1 這裡的 0 是一個單一值模式。只要 f 被給予 0 作為引數，這個模式就匹配，並且函式返回 1。對於任何其他引數，匹配失敗，因而這個函式也失敗。因為在函式定義中，語法上支援交替式模式，可以繼續將定義擴充套件為接受更一般性的引數： f n n f n1 這裡的第一個 n 是單一變數模式，它絕對的匹配任何引數，並將它繫結到名字 n，而用在定義的餘下部份之中。在 Haskell 中（至少不似 Hope），模式被依次嘗試，所以第一個定義仍適用於輸入是 0 的非常特殊情況，而對於任何其他引數，函式返回 n f n1，具有 n 是為引數。 萬用字元模式（通常寫為_）也是簡單的：就像一個變數名字，它匹配任何值，但是不把這個值繫結到任何名字。在簡單字串匹配情況下的演算法，已經發展出很多遞迴和非遞迴的變體。 在 Haskell 中，下面的程式碼定義了一個代數資料型別 Color，它有一個單一的資料構造子 ColorConstructor，包裝一個整數和一個字串： data Color ColorConstructor Integer String 例如，要得到 Color 型別的整數部份的一個函式可以寫為： integerPart ColorConstructor theInteger _ theInteger 要得到字串部份： stringPart ColorConstructor _ theString theString 這些函式可以透過 Haskell 的資料記錄語法自動建立。 模式匹配還可應用來過濾特定結構的資料。例如，在 Haskell 中可以使用列表推導式進行這種過濾： data ABint A Int B Int A xA x A 1 B 1 A 2 B 2 求值結果為： A 1 A 2 序列模式 從上述原始模式，可以建造更加複雜的模式，通常採用的方式，相同於透過組合其他值來建造值。區別在於，具有變數和萬用字元部份，模式不建造成一個單一值，而是匹配一組值，它們是具體元素和允許在模式結構內變化的元素的組合。 在 Haskell 和一般的函數語言程式設計語言中，列表是主要資料結構，它通常被定義為一種典型的代數資料型別： data List a Nil Cons a List a Cons 是構造（construct）的簡寫。很多語言針對以這種方式定義的列表提供特殊語法。例如，Haskell 和 ML，分別將 用於 Nil， 或：用於 Cons，並將方括號用於整個列表。所以通常在 Haskell 中寫為或，在 OCaml 中寫為或。 列表被定義為空列表，或一個元素構造在一個現存的列表上。在 Haskell 語法下寫為： 空列表 xxs 元素 x 構造在列表 xs 之上 具有一些元素的一個列表的結構，就是 elementlist。在模式匹配的時候，斷定特定部份的資料等於特定模式。例如，在如下函式中： head elementlist element 這裡斷定了 head 的實際引數的第一個元素被稱為 element，並且這個函式返回這個元素。之所以知道它是第一個元素的，是因為列表的定義方式，它是一個單一元素構造在一個列表之上，這個單一元素必定是第一個元素。空列表根本不匹配這個模式，因為空列表沒有頭部（要構造的第一個元素）。 在這個例子中，我們沒有用到 list，可以漠視它，而將函式寫為： head element_ element 樹狀模式 樹狀模式一般用來匹配由遞迴資料型別生成的複雜的樹狀結構，比如程式語言抽象語法樹。它透過開始於一個節點，指定某些分支以及節點，並且透過變數或萬用字元留下一些不指定，來描述一個樹的一部份。 下面是在 OCaml 下，定義一個紅黑樹和在元素插入後再平衡的函式的例子： type color Red Black type a tree Empty Tree of color a tree a a tree let rebalance t match t with Tree Black Tree Red Tree Red a x b y c z d Tree Black Tree Red a x Tree Red b y c z d Tree Black a x Tree Red Tree Red b y c z d Tree Black a x Tree Red b y Tree Red c z d Tree Red Tree Black a x b y Tree Black c z d _ t the catchall case if no previous pattern matches 字串模式 迄今最常用形式的模式匹配涉及字串。在很多程式語言中，使用特定的字串語法來表示正則表示式，它是描述字串的模式。 在 Haskell 中，如下模式匹配有兩個字元並且開始於 a 的字串 a _ 可以介入符號式實體，來表示一個字串的很多不同類的有關特徵。在 Haskell 中，可以使用守衛來進行匹配： letter digit isAlpha letter isDigit digit 它將匹配首個字元是一個字母，接著的是一個數字的字串。 符號式字串操縱的主要好處，是它可以與程式語言的其餘部份完全的整合，而非成為一個獨立的、專用的子單元。這個語言的整體能力，可以放大到建造模式自身，或分析和變換包含它們的程式。 Python 的模式匹配 定義 在 Python 版本 310 中，模式匹配的語法應該是： match subject case pattern_1 action_1 case pattern_2 action_2 case pattern_3 action_3 case _ action_wildcard 其中 subject 表示原始資料，pattern_ 表示不同模式，_表示萬用字元，如果在上文中沒有找到精確匹配的物件，將會使用萬用字元。如果一個模式匹配沒有精確匹配上且沒有萬用字元，整個語句不做任何作用（noop）。 例子 在 Python 版本 310 中： def http_error status match status case 400 return Bad request case 404 return Not found case 418 return Im a teapot case _ 省略此行及下一行以創造一個沒有萬用字元的模式匹配 return Somethings wrong with the Internet 如果省略最後兩行，當 status 為 500 時什麼都不會發生。 同理，模式匹配也可用於 class 中： class Point x int y int def location point match point case Point x0 y0 print Origin is the points location case Point x0 yy print fYy and the point is on the yaxis case Point xx y0 print fXx and the point is on the xaxis case Point print The point is located somewhere else on the plane case _ print Not a point 和其他語言中的模式匹配一樣，Python 中也可以在匹配的語句中使用萬用字元： match test_variable case warning code 40 print A warning has been received case error code _ print fAn error code occurred 引用 外部連結 Nikolaas N Oosterhof Philip K F Hölzenspies and Jan Kuper Application patterns A presentation at Trends in Functional Programming 2005 JMatch the Java programming language extended with pattern matching ShowTrend Online pattern matching for stock prices An incomplete history of the QED Text Editor by Dennis Ritchie provides the history of regular expressions in computer programs The Implementation of Functional Programming Languages pages 53103 Simon Peyton Jones published by Prentice Hall 1987 Nemerle pattern matching Erlang pattern matching Prop a C based pattern matching language 1999 PatMat a C pattern matching library based on SNOBOL Temur Kutsia Flat Matching Journal of Symbolic Computation 43 12 858873 Describes in details flat matching in Mathematica EasyPattern language pattern matching language for nonprogrammers Category 條件結構 Category 函數語言程式設計