文字列パターンの操作

はじめに
Wolfram言語の一般的な記号文字列パターンを使って,強力な文字列操作を効率よく行うことができる.このドキュメントは,文字列パターンの詳細について,使用法と実装に関するノートを含めて説明するものであり,ヘルプシステム他の箇所では扱われていない点を特に詳述する.
Wolfram言語の中心にあるのは通常の式でパターンを記述する強力な言語である.この言語は関数の定義,置換,検索,x_a|bx..のようなコンストラクト等に使われている:
Wolfram言語の文字列パターンは,同じコンストラクトを使ってテキスト文字列中のパターンを記述する.文字列を文字が連続するものと考えて,一般的なWolfram言語パターンの原則を適用することができる.さらに,文字列特有のパターンコンストラクトもいくつかある:
文字列パターンを指定する別の方法として,正規表現を使うこともできる.この方がよりコンパクトになることが多いが,読みにくい:
次は文字列パターンを認識するいくつかの関数である.
StringMatchQ["s",patt]
spatt にマッチするかどうか判定する
StringFreeQ["s",patt]
spatt にマッチする文字列が含まれていないかどうか判定する
StringCases["s",patt]
patt 中の s の部分文字列のリストを与える
StringCases["s",lhs->rhs]
lhsrhs で置き換える
StringPosition["s",patt]
patt にマッチする部分文字列の位置のリストを与える
StringCount["s",patt]
いくつの部分文字列が patt にマッチするか数える
StringReplace["s",lhs->rhs]
lhs にマッチするすべての部分文字列を置き換える
StringReplaceList["s",lhs->rhs]
lhs を置換するすべての方法をリストする
StringSplit["s",patt]
patt にマッチするすべての部分文字列のところで s を分割する
StringSplit["s",lhs->rhs]
lhs で分割し rhs を挿入する
文字列パターンをサポートする関数
一般的な文字列パターン
一般的な文字列パターンは,Wolfram言語のパターンオブジェクトに類似のパターンオブジェクトによって形成される.複数のパターンオブジェクトの結合にはStringExpression演算子~~を用いる:
StringExpressionStringJoinと非常に似ている.異なる点は前者は文字列ではないものも許容し,リストを平坦化しない点である.純粋な文字列の場合,両者は等しい:
文字列で使うことができるオブジェクトのリストは,通常のWolfram言語パターンのリストとほぼ一致する.文字列パターンに関しては,文字列は一連の文字とみなされる.すなわち,"abc"は,通常のパターンコンストラクトが適用できるString[a,b,c]のようなものとみなされる.
次のオブジェクトは記号的な文字列パターンで使える.
"string"
文字列
_
単一の文字
__
1つまたは複数の文字の入った部分文字列
___
文字が入ったまたは入らない部分文字列
x_
,
x__
,
x___
x という名の部分文字列
x:pattern
x という名のパターン
pattern..
1回あるいは複数回繰り返されたパターン
pattern...
繰り返されたあるいは繰り返されなかったパターン
{patt1,patt2,}
または
patt1|patt2|
patti の少なくとも1つにマッチするパターン
patt/;cond
cond を評価するとTrueになるパターン
pattern?test
各文字について testTrueを返すパターン
Whitespace
空白類文字の文字列
NumberString
数の文字
DatePattern[spec]
日付の文字列
charobj
文字のクラスを繰り返すオブジェクト(以下参照)
RegularExpression["regexp"]
正規表現にマッチする部分文字列
StringExpression[]
任意の文字列式
次は,文字クラスを表す
{c1,c2,}
"ci"のいずれか
Characters["c1c2"]
"ci"のいずれか
CharacterRange["c1","c2"]
"c1"から"c2"
HexadecimalCharacter
16進数字09,af,AF
DigitCharacter
0から9までの数字
LetterCharacter
文字
WhitespaceCharacter
スペース,改行,タブ,その他の空白類文字
WordCharacter
文字または数字
Except[p]
p に一致するもの以外の任意の文字
次は,文字列中の位置を表す
StartOfString
文字列全体の先頭
EndOfString
文字列全体の末尾
StartOfLine
行頭
EndOfLine
行末
WordBoundary
文字記号とその他の境界
Except[WordBoundary]
文字の境界以外の任意の場所
以下は複数の可能性がある場合にどのマッチを取るかを決める
Shortest[p]
p にマッチする最短のもの
Longest[p]
p にマッチする最長のもの(デフォルト)
以下はこれらのオブジェクトに関する重要な問題である.
______のワイルドカードは,改行を含むどの文字にもマッチする.改行以外のすべての文字にマッチするようにするのには(正規表現の"."のように),Except["\n"]Except["\n"]..Except["\n"]...を使う:
{"a","b","c"}のようなパターンのリストは,"a"|"b"|"c"のような代替物のリストと等価である.CharactersCharacterRangeのような関数を文字クラスの指定に使うことができるので,これは便利である:
Condition(/;)が使われると,Wolfram言語の他の部分に関する限り,これに含まれるパターンは文字列として扱われる.このため,場合によってはToExpressionを使わなければならないことがある:
通常のWolfram言語パターンと同様に,PatternTest(?)の関数も各文字それぞれに適用される:
WhitespaceコンストラクトはWhitespaceCharacter..と等価である:
通常の文字列パターンにRegularExpressionオブジェクトを挿入することができる:
これは,"the "が前にある単語だけを拾ったことを確認するために,後読みの制約条件(「正規表現」参照)を挿入する:
StringExpressionオブジェクトはネストさせることができる:
文字列パターンのExceptコンストラクトは,単一の文字,あるいは単一の文字クラスを表す単一引数を取る.
次は,文字列から母音以外のすべての文字を削除する:
異なる長さのパターン(__patt..等)をマッチさせようとするときは,デフォルトで,可能な最長マッチがまず試される.最初に最短マッチを試させるのには,パターンの関連箇所をShortest[ ]で包み込む:
何らかの理由で最短マッチ中の最長マッチが必要な場合には,Longestを使うことができる:
Longestを使う代りにパターンを書き換えてもよい:
正規表現
正規表現のシンタックスは,その元になっているPCRE(Perl準拠正規表現)ライブラリに従っている.このライブラリはPerlのシンタックスにきわめて近い(詳細は[1]を参照のこと). Wolfram言語の正規表現は RegularExpressionという頭部で示される.
正規表現文字列で,次の基本要素が使える.
c
文字通りの文字 c
.
新規行以外の任意の文字
[c1c2]
ci 中の任意の文字
[c1-c2]
c1から c2の範囲の任意の文字
[^c1c2]
ci 以外の任意の文字
p*
繰り返されたあるいは繰り返されなかった p
p+
繰り返された p
p?
現れたあるいは現れなかった p
p{m,n}
m 回から n 回繰り返された p
p*?
,
p+?
,
p??
マッチする最短の文字列
p*+
,
p++
,
p?+
プログレッシブマッチ
(p1p2)
p1, p2, にマッチする文字列
p1|p2
p1 あるいは p2にマッチする文字列
次は文字のクラスを表す
\\d
0から9までの数字
\\D
数字ではないもの
\\s
スペース,改行,タブ,その他の空白類
\\S
空白類文字ではないもの
\\w
文字記号(文字,数字,あるいは _
\\W
非文字記号
[[:class:]]
名前の付いたクラス中の記号
[^[:class:]]
名前の付いたクラスには含まれない記号
次の名前付きクラスが使える:alnumalphaasciiblankcntrldigitgraphlowerprintpunctspaceupperwordxdigit
次は,文字列中の位置を表す.
^
文字列(あるいは行)の先頭
$
文字列(あるいは行)の末尾
\\A
文字列の先頭
\\z
文字列の末尾
\\Z
文字列の末尾(はじめに改行文字を1字許す)
\\b
語の区切り
\\B
語の区切り以外の任意の場所
以下は,それに続くすべての正規表現要素にオプションを設定する
(?i)
大文字小文字を等しいものとして扱う(大文字小文字の区別をしない)
(?m)
^$が行の先頭と末尾に一致する(マルチラインモード)
(?s)
.を改行にマッチさせる
(?x)
すべての空白文字類を無視し"#""\n"の間にあるものすべてをコメントとして扱う
(?-#c)
オプションを解除する
次は,先読み/後読みコンストラクトである.
(?=p)
後続するテキストは p にマッチしなければならない
(?!p)
後続するテキストは p にマッチしなければならない
(?<= p)
先行しているテキストは p にマッチしなければならない
(?<!p)
先行しているテキストは p にマッチしなければならない
以下は,正規表現を巡る問題に関する若干の考察である.
次は,長さが2から4の一連の単語文字を探す:
所有を表す"+"量限定子を付けると,マッチャーによって可能な限り多くの文字が取り出され,1文字たりとも見逃されない.これは,たとえパターンの他の部分でそうするようになっていても変わらない:
[[:xdigit:]]は16進法の文字に対応する:
.\?(){}[]^$*+|正規表現でエスケープしなければならない文字の完全リストである.例えば,文字通りのピリオドを書く際には"\\."を使い,文字通りのバックスラッシュを書く場合には"\\\\"を使う.
文字クラス"[]"の中でのエスケープされる文字の完全リストは^-\[]である.
デフォルトにより,^$は,それぞれ文字列の先頭と末尾にマッチする.マルチラインモードでは,これらは行の先頭/末尾にマッチする:
マルチラインモードでは,文字列の先頭と末尾を表すのに\\A\\Zを使うことができる:
読みやすくするために,(?x)限定子を使って正規表現に空白文字やコメントを入れることができる:
名前付きのサブパターンは,(subpatt)のように前後にカッコを置く.こうすると番号付きのサブパターンとなる.指定のサブパターンの番号は開きカッコを数え,カッコのはじめから始める.この場合,n 番目のサブパターンは\\n で参照することができる.規則の右辺では"$n"を使うことができる."$0"はマッチしたすべてのパターンを参照する:
このコンテキスト(左辺の頭部がRegularExpression)で文字通りの$が必要な場合には,バックスラッシュを使ってこれをエスケープすることができる(例:"\\$2"):
このような状況下で,文字通りのシングルバックスラッシュに文字通りの$が続いたものが必要なときは,多少手の込んだ方法を用いて,一時的に文字列を2つに分割する必要がある:
パターンの一部をグループ化する必要があるが,そのグループを番号付きの部分パターンには数えたくない場合には,(?:patt)コンストラクトを使うことができる:
先読みと後読みのパターンは,マッチの一部としてテキストを実際に含まずに,パターンがマッチしていることを確実にするために使われる.
以下は文字列"the "に後続する単語を選び出す:
これは,文字列中のすべての偶数を拾い出し,パーシャル数を含むマッチを探し出す:
先読み/後読みを使うと,マッチの前/後が数字ではないことが確認できる(後読み判定は場合によっては余分になるので注意のこと):
RegularExpressionとStringExpression
一般的な記号文字列パターンで使われるパターンオブジェクトと正規表現で使われるそれとの間には,密接な対応関係がある.以下は正規表現で書かれたものと記号文字列パターンで書かれたものの例のリストである.
正規表現
一般的な文字列パターン
説明
"abc""abc"
文字通りの文字列 "abc"
"."Except["\n"]
改行以外の任意の文字
"(?s)."_
任意の文字
"(?s).+"__
1つ以上の文字(最長マッチを行う)
"(?s).+?"Shortest[__]
1つ以上の文字(最長マッチは行わない)
"(?s).*"___
0以上の文字
".*"Except["\n"]...
0以上の文字(改行以外)
"a?b""a"|""~~"b"
0あるいは1個の"a""b"の前にある("b""ab"等)
"[abef]"Characters["abef"]
"a""b""e""f"のいずれかの文字
"[abef]+"Characters["abef"]..
任意の数の"a""b""e""f"の文字
"[a-f]"CharacterRange["a","f"]
"a"から"f"までの任意の文字
"[^abef]"Except[Characters["abef"]]
"a""b""e""f"以外の任意の文字
"ab|efg""ab"|"efg"
文字列"ab"あるいは"efg"とのマッチ
"(ab|ef)gh"
or
"(?:ab|ef)gh"
("ab"|"ef")~~"gh"
"ab"あるいは"ef""gh"が続くもの("abgh""efgh"
"\\s"WhitespaceCharacter
任意の空白文字
"\\s+"Whitespace
1つ以上の空白文字
"(a|b)\\1"x:"a"|"b"~~x_
"aa""bb"にマッチする
"\\d"DigitCharacter
任意の数字
"\\D"Except[DigitCharacter]
任意の非数字
"\\d+"DigitCharacter..
1つ以上の数字
"\\w"WordCharacter|"_"
任意の数字,文字列,あるいは"_"記号
"[[:alpha:]]"LetterCharacter
任意の文字
"[^[:alpha:]]"Except[LetterCharacter]
任意の非文字
"^abf"
or
"\\Aabc"
StartOfString~~"abf"
文字列の先頭にある文字列"abf"
"(?m)^abf"StartOfLine~~"abf"
行頭にある文字列"abf"
"wxz$"
or
"wxz\\z"
"wxz"~~EndOfString
文字列の末尾にある文字列"wxz"
"wxz\\Z""wxz"~~"\n"|""~~EndOfString
文字列の末尾あるいは改行の前にある文字列"wxz"
一般的な文字列パターンには使われるが,正規表現には使われないパターンオブジェクトには,マッチの間に一般的なWolfram言語コードにアクセスできる条件(/;),パターンテスト(?)等が含まれる.
一般的な文字列パターンでは直接使えない,正規表現の特別なコンストラクトもある.先読み/後読みや指定の長さの繰返し等がこれに当たる.これらはRegularExpressionオブジェクトを挿入することで,より大きな一般的文字列パターンに埋め込むことができる.
文字列操作関数
以下では,さまざまな文字列操作関数の特徴や細かい区別等について取り上げる(各関数の詳細はそれぞれのリファレンスページを参照のこと).

StringMatchQ

StringMatchQは,文字列全体が特定のパターンにマッチするかどうかを判定する:
(後読み互換性により)メタキャラクタの*@をワイルドカードとして含むことができる点で,StringMatchQは特別である.*Shortest[___] (RegularExpression["(?s).*?"])に等しく,@Except[CharacterRange["A","Z"]] (RegularExpression["[^A-Z]"])に等しい.
ゆえに,次の3つのパターンは等価である:
ここでは可能なマッチを探しているだけなので,技術的にはShortestの見かけに違いがない点に注意のこと.
パターン中のサブパターンでマッチした文字列の一部分にアクセスする必要がある場合は.StringCasesを使用する.
StringMatchQには,多少の矛盾を許容しながらマッチを求めるSpellingCorrectionオプションがある.これは,単一の文字列のみからなるパターンにのみ使用することができる:

StringFreeQ

StringFreeQは,ある文字列がパターンにマッチする部分文字列を含んでいるかどうかをチェックするのに使われる.マッチする部分文字列を抽出することはできない.抽出にはStringCasesを使う:

StringContainsQ

StringContainsQは,ある文字列がパターンにマッチする部分文字列を含んでいるかどうかをチェックするのに使われる.マッチする部分文字列を抽出することはできない.抽出にはStringCasesを使う:

StringStartsQ

StringStartsQは,ある文字列がパターンにマッチする部分文字列から始まるかどうかをチェックするのに使われる.マッチする部分文字列を抽出することはできない.抽出にはStringCasesを使う:

StringEndsQ

StringEndsQは,ある文字列がパターンにマッチする部分文字列で終るかどうかをチェックするのに使われる.マッチする部分文字列を抽出することはできない.抽出にはStringCasesを使う:

StringCases

StringCasesは,文字列中のパターンの生起を見付け,サブパターンを取り出し,結果を処理する一般的な目的関数である.
パターンに一致する部分文字列を求める:
マッチする部分文字列を拾う:
マッチの回数を制限する:
規則のリストを使うことができる:
多くの文字列を効率よく処理するために第1引数として文字列のリストを与えることもできる(「効果的なマッチングのヒント」の説明も参照のこと):

Overlapsオプション

StringCasesStringPositionStringCountOverlapsオプションは,マッチを見付けた後のマッチャーの進め方を扱う.可能な設定値はFalseTrueAllの3つである.デフォルト値は,StringCasesStringCountではFalseStringPositionTrueである.
Overlaps->Falseとすると,マッチャーは最後にマッチした部分文字列の後もテストを続ける:
Overlaps->Trueとすると,マッチャーは最後にマッチした部分文字列の最初の文字に続く文字からマッチを続ける(単一のパターンが含まれるとき):
Overlaps->Allとすると,マッチャーは新たなマッチが見付からなくなるまで同じ場所からマッチを探し続ける:
複数のパターンがリストで与えられている場合,Overlaps->Trueとするとマッチャーは各パターンにつき一度ずつ同じ場所からマッチを行ってから次の文字に移る:
Overlaps->Trueとすると,パターンのリストを指定した場合と代替演算子(|)を使った場合では違いが生ずる:

StringPosition

StringPositionは,マッチする部分文字列の位置を返す他はStringCasesと同じような働きをする:
OverlapsオプションはデフォルトではTrueである(このオプションの詳細は前節を参照のこと):
空文字列でさえもマッチされる:

StringCount

StringCountは,(StringPositionあるいはStringCasesで求められる)マッチする部分文字列の数を返す.これは,マッチが多く,すべての部分文字列を保存するためのメモリ量が問題となる場合に便利である:
StringCountのデフォルトはOverlaps->Falseである.

StringReplace

StringReplaceは,与えられたパターンにマッチする部分文字列を代替するのに使われる
置換規則の右辺の文字列として名前付きパターンを使うことができる.RuleDelayed ()を使って時期尚早の評価を避ける点に注意のこと:
正規表現を使う場合は,右辺の"$0"はマッチする文字列全体を参照することを覚えておくと便利である:
第3引数を指定して置換数を制限することができる:
置換は文字列に限られない.結果が文字列でなければ,StringExpressionが返される:
一般的な文字列パターンと関連して,旧MetaCharactersを使う際のサポートは限られている.このオプションは廃止される予定なので,使用は避けるべきである.

StringReplaceList

StringReplaceListは,すべての可能な方法で単一の文字列置換が行われた文字列のリストを返す:
文字列のリストが入力として与えられると,出力は結果のネストしたリストになる:

StringSplit

StringSplitは,パターンにマッチする区切りで文字列を分割するのに便利である.デフォルトでは,分割は一連の空白文字の位置で行われる:
例えば,通常の文を単語に区切るのには,区切りに句読点も含まなければならない:
デフォルトにより,結果の冒頭と末尾にある空白文字列は移動される:
Allを第3引数として指定することで,これらを含めることができる:
第3引数は,文字列の最大区切り数を表す数でもよい:
これは,文字列を個々の行に分割する:
StartOfLineのように,位置にマッチするパターンで区切ることもできる.これは,結果に改行記号を残す:
規則を第2引数として使って,区切りあるいは区切りの一部分を出力に残すこともできる:
パターンや規則のリストを与えることもできる.パターンにマッチする区切りは結果から除かれる:
Perlユーザのために

はじめに

一般的な文字列パターンを加えることで,Wolfram言語は一般的かつ日常的なプログラミングタスクにおいてPerlやPythonのような言語に変わる強力なものになった.次は,Perlのシンタックスや文字列操作に馴染んでいる人のための,同様な機能をWolfram言語で使うための簡単な説明である.
以下はPerlに似た関数を構築するために使用されるWolfram言語関数の概観である.
Perlコンストラクト
Wolfram言語関数
説明
m/ .../StringFreeQ
または
StringCases
文字列を正規表現でマッチする.サブパターンを抽出することもある
s/ .../ .../StringReplace
正規表現にマッチする部分文字列を置換する
split(...)StringSplit
正規表現にマッチする区切りの位置で文字列を分割する
tr/ .../ .../StringReplace
文字を他の文字で置換する
/iIgnoreCase->True
または
"(?i)"
大文字小文字の区別をしない限定子
/s"(?s)"
"."が改行を含むすべての文字にマッチするように強制する
/x"(?x)"
空白文字類を無視し,正規表現による拡張されたコメントを許容する
/m"(?m)"
マルチラインモード("^"および"$"が行頭/行末に対応)
以下はPerlの一般的なコンストラクトのいくつかについてのより詳細な説明である.

m/.../

マッチ演算子m/regex/が,文字列にregexにマッチする部分文字列が含まれているかどうかを検証する.Wolfram言語では,この種の簡単なマッチにStringFreeQを用いる.
次は,文字列で,の後ろにが含まれているかどうかを検証するためのPerlの断片である:
次は同様の検証をWolfram言語で行う方法である:
マッチした文字列の一部に後でアクセスする必要がある場合は,Perlでは, , を用いる.Wolfram言語の関数で最もよいのは一般にStringCasesである.
次はエラーメッセージを抽出するPerlコードである:
次はWolfram言語によるものである:
次は複数のサブパターンを一度に抽出するPerlのコードである:
Wolfram言語では,StringCasesを使ってこれを行う:
これは限定子を用いてすべてのマッチを配列に割り当てるのに似ている:
Wolfram言語では,StringCasesを用いて同じことが簡単に行える:

s/.../.../

Perlの代替演算子はWolfram言語ではStringReplaceになる:
デフォルトのPerlの動作は単一置換である:
Perlの限定子はすべてのマッチを大域的に置換する:
評価の限定子を使うことで,Perlではサブパターンを置換の一部として使うことができる.これはWolfram言語でも容易に行うことができる:

split(...)

PerlのコマンドはWolfram言語のStringSplitによく似ている:
PerlでもWolfram言語でも,分割後のブロック数を指定することができる:
パターン中のカッコをとらえたは,とらえられた部分文字列が結果に含まれるのだが,Wolfram言語ではStringSplitの第2引数として規則を使うことで簡単に行うことができる.Perlに比べ,Wolfram言語では,これらの部分文字列に簡単に関数を適用できる:

tr/.../.../

Perlのコマンドは,Wolfram言語ではStringReplaceと規則のリストを一緒に使うことでまねることができる.
次はその最も簡単な形で,, , , , でそれぞれ置換されている:
次はWolfram言語でThreadを使った適切な規則を生成する:
次は,置換リストが文字のリストよりも短いために,がすべてで置換されている例である:
Perlにおける文字領域は,Wolfram言語ではCharacterRangeを用いてまねられる:
限定子を使うと,余分な文字が削除される:
限定子を使うと,文字リストの補完が使われる:
限定子は文字の任意の連なりを同じ文字に絞り込む:
Wolfram言語でRepeated (..)を使っても同じことができる:
例題
このセクションでは文字列パターンの実際的な例をいくつか取り上げる.

パターンのハイライト

これは,基底が1000のランダムなDNA配列である :
次で,特定のパターンにマッチするDNAの部分をハイライトする:
同様の結果を正規表現で出してみる:

HTMLの解析

文字列パターンは生のHTMLから情報を抽出するのに便利である.
これはwww.google.comから取ったソースである:
ソースにある直接のハイパーリンクすべてを抽出してみる:
これは<>というタグの内側にあるものをすべて削除する:

金額の検索

ここにあるテキストをスキャンしてドル表示の金額を表していると思われる文字列を抽出する:
上記を行う方法の1つに記号文字列パターンを使うものがある:
正規表現を用いて同じ結果を得る(ドル記号をエスケープするのを忘れないように):
この場合は組込みのパターンオブジェクトNumberStringを使うこともできる:

ファイル中のテキストの検索

これは,指定のパターンにマッチするテキストを含んだ行を検索する,グレップに似た非常に単純な関数である:
これで,サンプルのテキストファイルを作る:
これは,"text.txt"中の数字を含む行と行番号を返す:
これは,"a"を単独の語として含んでいる行を検索する:
効率的なマッチングのヒント
このセクションでは,文字列パターンマッチの効率に関する問題を扱う.

StringExpressionとRegularExpression

Wolfram言語のシンタックスで書かれた文字列パターンは,即座に正規表現に変換され,ついでコンパイル,キャッシュされるので,正規表現のシンタックスを直接使うのに対してWolfram言語のシンタックスを使うことのオーバーヘッドはほとんどない.しかし例外として,多くの異なるパターンが何度か使われると明確なオーバーヘッドが起ることがある.

条件とパターンテスト

パターンにCondition (/;)あるいはPatternTest (?)文が含まれていると,マッチングの間にWolfram言語の評価装置が呼び出されるため,マッチングが遅くなる.上記のようなコンストラクトなしでパターンが書ける場合は,一般にこちらの方が速い:

ネストした量限定子を避ける

マッチに使われている非決定性有限オートマトン(NFA)アルゴリズムのために,ネストした量限定子(__patt..あるいは正規表現でこれらに当たるもの等)を含んだパターンは非常に遅くなることがある.このようなパターンは,より効率のよいバージョンに「展開」することができる(詳しくはFriedl[2]を参照のこと).

関数を何度も呼び出すのを避ける

何らかのマッチを探して長いリストを検索しているなら,SelectStringMatchQ等を使うよりも,リスト全体を文字列関数に一度にフィードした方が効率が上がる(前述の辞書の例を参照されたい).次の例は,10字からなっている文字列を2000個生成し,その中から"a"で始まり"ggg"という部分文字列を含んだものを探し出す:
こちらはSelectStringMatchQを使ったもので,速度が劣る:
StringMatchQにリスト全体を一度にフィードすると,ずっと速くなる.その後,Pickを使って希望の要素を抽出する:
また,StringCasesを使うこともできる.こちらも速い."a"が語頭にくるようにStartOfStringを使ってパターンを固定する必要がある(EndOfStringは,この例には過剰である):

通常の表現による検索を文字列検索に書き換える

文字列マッチングのアルゴリズムは,Wolfram言語が一般の式のマッチングに使うアルゴリズムとは異なるので(文字列マッチングは有限個のアルファベットと平坦な構造を仮定することができる等),通常の式のマッチングにおける問題を文字列マッチングの問題に置き換えて考えると都合がいいことがある.典型的な例として,記号の長いリストを_____が何度か現れるパターンとマッチさせる例を考える.
(例えば,1000000以降の)少なくとも4つの数字が同じ素数を見付けたい場合を例にとってみる.通常のパターンマッチングを使うと,次のようになるだろう:
整数のリストを文字列に変換することで,文字列マッチングが使えるようになる:
PickStringCasesを使うという前述のヒントに従って,さらにスピードアップを図ることができる:
長い文字列の場合は,違いが大きくなる:
実装の詳細
Wolfram言語における文字列パターンのマッチングは,Philip Hazel[1]によるPCRE(Perl準拠の正規表現)ライブラリの上に構築されている.
ところによっては5.1以前のWolfram言語のアルゴリズムが使われている(例:パターンが単一の文字通りの文字列の場合等).
記号的文字列パターンはどれも,まず正規表現に変換される.この変換は内部的なStringPattern`PatternConvert関数を使って見ることができる:
返される最初の要素は正規表現である.その他の要素は条件や置換規則,名前付きパターン等に関連するものでなければならない.
次に正規表現がPCREによってコンパイルされ,コンパイルされたものは,将来的に同じパターンが再び現れたときに使うためにキャッシュされる.記号的な文字列パターンから正規表現への変換は1度しか行われない.
パターンにおけるWolfram言語の条件は,PCREライブラリからWolfram言語の評価装置の外部的呼び出しによって処理される.これによってマッチングが遅くなる.
一般的な文字列パターンに埋め込まれた明示的なRegularExpressionオブジェクトは,(キャプチャしないカッコ"(?:...)"で挟まれた)最終的な正規表現に組み継がれるので,名前付きパターンを数えると予想と食い違うかもしれない.
PCREは現在のところ文字コード規格255を超えるあらかじめセットされた文字クラスはサポートしていないので,単語と文字のクラス(WordCharacterLetterCharacter等)にはUnicodeの領域0-255にある文字コードのみが含まれる.このため,LetterCharacterおよび_?LetterQは文字コード規格255を超えた同等の結果は与えない.
PCREの同じような制限のため,(IgnoreCase->True等での)大文字小文字を区別しないマッチングはUnicodeの0-127の範囲にある文字(英語では通常"a""z""A""Z")にのみ適用される.
参考文献

[1] Hazel, P. "PCREPerl Compatible Regular Expressions." (2004). www.pcre.org

[2] Friedl, J. E. F. Mastering Regular Expressions, 2nd ed. O'Reilly & Associates, 2002.