クイックスタート
チュートリアル
ツールと言語
リファレンス
書評
正規表現ツール
grep
PowerGREP
RegexBuddy
RegexMagic
汎用アプリケーション
EditPad Lite
EditPad Pro
言語とライブラリ
Boost
Delphi
GNU (Linux)
Groovy
Java
JavaScript
.NET
PCRE (C/C++)
PCRE2 (C/C++)
Perl
PHP
POSIX
PowerShell
Python
R
Ruby
std::regex
Tcl
VBScript
Visual Basic 6
wxWidgets
XML スキーマ
Xojo
XQuery と XPath
XRegExp
データベース
MySQL
Oracle
PostgreSQL
このサイトについて、さらに
はじめに
正規表現 クイックスタート
正規表現 チュートリアル
置換文字列 チュートリアル
アプリケーションと言語
正規表現の例
正規表現 リファレンス
置換文字列 リファレンス
書評
印刷可能な PDF
このサイトについて
RSS フィードとブログ
RegexBuddy—The best regex editor and tester for Tcl developers!

Tcl には 3 つの正規表現フレーバーがあります

Tcl 8.2 以降では、3 つの正規表現フレーバーがサポートされています。Tcl のマニュアルページでは、それらを基本正規表現 (BRE)、拡張正規表現 (ERE)、高度正規表現 (ARE) と呼んでいます。BRE と ERE は、主に以前のバージョンの Tcl との互換性のために存在します。これらのフレーバーは、POSIX 標準で定義されている 2 つのフレーバーを実装しています。ARE は Tcl 8.2 で新しく追加されました。これはデフォルトであり、推奨されるフレーバーです。このフレーバーは POSIX ERE フレーバーを実装しており、多くの機能が追加されています。これらの機能のほとんどは、Perl の正規表現の同様の機能から着想を得ています。

Tcl の正規表現サポートは、Henry Spencer によって Tcl のために開発されたライブラリに基づいています。このライブラリは、PostgreSQL データベースや C++ 用の wxWidgets GUI ライブラリなど、他の多くのプログラミング言語やアプリケーションで使用されています。この正規表現のチュートリアルで Tcl について述べられていることはすべて、Henry Spencer の高度正規表現を使用するツールにも適用されます。

Tcl の高度正規表現と Perl スタイルの正規表現の間には、いくつかの重要な違いがあります。Tcl は\m, \M, \yそして\Y単語境界に使用します。Perl と他のほとんどの最新の正規表現フレーバーは\bそして\Bを使用します。Tcl では、これら 2 つはそれぞれバックスペースとバックスラッシュに一致します。

Tcl はモード修飾子にも全く異なるアプローチを取っています。(?letters)構文は同じですが、使用可能なモード文字とその意味は大きく異なります。正規表現にモード修飾子を追加する代わりに、-nocaseのようなより記述的なスイッチをregexpそしてregsubコマンドに渡すことができます。いくつかのモードでは、(?modes:regex)スタイルのモード修飾子の範囲はサポートされていません。モード修飾子は正規表現の先頭に表示する必要があります。それらは正規表現全体に影響します。正規表現内のモード修飾子は、コマンドスイッチをオーバーライドします。Tcl は次のモードをサポートしています。

の古い同義語です。Tcl と他のプログラミング言語で正規表現を使用する場合は、改行関連のマッチングモードを扱う際に注意してください。Tcl の設計者は、Perl の/mそして/sモードをわかりにくいと考えていました。確かにわかりにくいですが、少なくとも Perl には 2 つだけで、どちらも 1 つのものだけに影響します。Perl では、/mまたは(?m)は「複数行モード」を有効にし、これによりキャレットとドル記号が改行文字の前後にも一致します。デフォルトでは、文字列のまさに先頭と末尾のみに一致します。Perl では、/sまたは(?s)は「単一行モード」を有効にします。このモードでは、ドットは改行文字を含むすべての文字に一致します。デフォルトでは、改行文字には一致しません。Perl には、否定文字クラスから改行文字を除外するためのモード修飾子はありません。Perl では、[^a]は、a以外のすべての文字(改行文字を含む)に一致します。改行文字を除外する唯一の方法は、[^a\n]と記述することです。Perl のデフォルトのマッチングモードは Tcl の(?p)に似ていますが、否定文字クラスが異なります。

なぜ Tcl と Perl を比較するのでしょうか?.NETJavaPCREPythonなど、多くの一般的な正規表現フレーバーは、Perl とまったく同じデフォルトと効果で同じ(?m)そして(?s)修飾子をサポートしています。否定文字クラスは、これらのすべての言語とライブラリで同じように動作します。Tcl が Perl の標準に従わなかったのは残念です。Tcl の 4 つのオプションは、Perl の 2 つのオプションと同じくらいわかりにくいためです。これらはまとめて、非常に分かりにくいアルファベットスープを作ります。

Tcl のオプションが否定文字クラスに影響を与えるという事実を無視すれば、次の表を使用して、Tcl の改行モードと Perl スタイルの改行モードの間を変換できます。デフォルトは異なることに注意してください。スイッチを使用しない場合、(?s).そして.は Tcl では同等ですが、Perl では同等ではありません。

TclPerlアンカードット
(?s)(デフォルト)(?s)文字列の先頭と末尾のみ任意の文字
(?p)(デフォルト)文字列の先頭と末尾のみ改行文字以外の任意の文字
(?w)(?sm)文字列の先頭と末尾、および改行文字の位置任意の文字
(?n)(?m)文字列の先頭と末尾、および改行文字の位置改行文字以外の任意の文字

Tcl の単語としての正規表現

Tcl のソースコードに正規表現を挿入するには、二重引用符で囲む(例:"my regexp")か、波括弧で囲む(例:{my regexp})ことができます。波括弧は引用符のように置換を行わないため、正規表現にははるかに適しています。

唯一の懸念事項は、正規表現内のエスケープされていない波括弧がバランスが取れている必要があることです。エスケープされた波括弧はバランスが取れている必要はありませんが、波括弧のエスケープに使用されたバックスラッシュは正規表現の一部として残ります。正規表現内のリテラルな波括弧をすべてエスケープし、繰り返し子として使用されている波括弧を除外することで、これらの要件を簡単に満たすことができます。このようにすると、正規表現は期待通りに動作し、Tcl のソースコードに貼り付ける際に変更する必要はありません(波括弧で囲むことを除く)。

正規表現^\{\d{3}\\$は、開始波括弧、3 桁の数字、1 つのバックスラッシュで構成される文字列に一致します。Tcl では、これは{^\{\d+{3}$\\}になります。正規表現内のリテラルな波括弧をエスケープする限り、バックスラッシュを二重にする必要も、エスケープする必要もありません。{そして\{はどちらも、Tcl ARE(そしてあらゆる Perl スタイルの正規表現フレーバー)で単一の開始波括弧に一致させる有効な正規表現です。後者のみが、波括弧で囲まれた Tcl リテラルで正しく動作します。

正規表現のマッチングの検索

Tcl では、regexp文字列の一部に正規表現が一致するかどうかをテストし、一致した部分を取得するためのコマンドです。コマンドの構文は次のとおりです。

regexp ?スイッチ? regexp subject ?matchvar? ?group1var group2var ...?

直後にregexpコマンドを配置し、上記の一覧から0個以上のスイッチを配置して、Tclが正規表現をどのように適用するかを指定できます。必須のパラメータは、正規表現と対象文字列のみです。先ほど説明したように、中括弧を使用してリテラルの正規表現を指定できます。または、ファイルまたはユーザー入力から読み取った正規表現を保持する文字列変数を参照することもできます。

追加の引数として変数の名前を渡すと、Tclは正規表現によって一致した文字列の部分を変数に格納します。一致の試行に失敗した場合でも、Tclは変数を空文字列に設定しません。正規表現にキャプチャグループがある場合、各グループによって一致したテキストをキャプチャするために、追加の変数名を指定できます。正規表現のキャプチャグループよりも少ない変数を指定した場合、追加のグループによって一致したテキストは格納されません。正規表現のキャプチャグループよりも多くの変数を指定した場合、全体的な正規表現の一致が成功した場合は、追加の変数は空文字列に設定されます。

このregexpコマンドは、文字列の一部が一致した場合は1を、一致しない場合は0を返します。次のスクリプトは、正規表現my regexを、変数に格納されている文字列に対して大文字小文字を区別せずに適用し、結果を表示します。subjectstringコマンドは、正規表現モード修飾子ではない3つのスイッチをさらにサポートしています。

if [
  regexp -nocase {my regex} $subjectstring matchresult
] then {
  puts $matchresult
} else {
  puts "my regex could not match the subject string"
}

このregexpこの-allスイッチにより、コマンドは正規表現が何回一致したかを示す数値を返します。正規表現とグループの一致を格納する変数には、文字列の最後の一致のみが格納されます。

この-inlineスイッチはregexpコマンドに、正規表現によって一致した部分文字列と、すべてのキャプチャグループによって一致したすべての部分文字列を含む配列を返すように指示します。また-allスイッチを指定した場合、配列には最初の一致する正規表現、最初の一致のすべてのグループ一致、次に2番目の一致する正規表現、最初の一致のグループ一致などが含まれます。

この-startスイッチの後に、Tclが一致を試みる対象文字列の文字オフセットを示す数値(別のTclワードとして)を指定する必要があります。開始位置より前のものはすべて、正規表現エンジンからは見えなくなります。つまり、\Aは、指定した文字オフセットで一致し-startます。その位置が文字列の先頭ではない場合でも同様です。

正規表現の一致の置換

このregsubコマンドを使用して、文字列内の正規表現の一致を置換できます。

regsub ?switches? regexp subject replacement ?resultvar?

コマンドと同様に、regexpは、0個以上のスイッチに続いて正規表現を取ります。ただし、regsubを除く、同じスイッチをサポートしています。-inline文字列内のすべての一致を置換する場合は、-allを指定してください。

正規表現の後の引数は、置換テキストである必要があります。中括弧構文を使用してリテラルの置換を指定するか、文字列変数を参照できます。regsubコマンドは、置換テキスト内のいくつかのメタ文字を認識します。全体の一致には\0を使用し、\1から\9までは、最初の9個のキャプチャグループのいずれかによって一致したテキストに使用できます。また、&\0の同義語として使用できます。アンパサンドの前にバックスラッシュがないことに注意してください。&は全体の一致で置換され、\&はリテラルのアンパサンドで置換されます。リテラルのバックスラッシュを挿入するには、\\を使用します。バックスラッシュの後に数字が続く場合にのみ、バックスラッシュをエスケープする必要があります。これにより、組み合わせが後方参照として認識されるのを防ぎます。繰り返しになりますが、バックスラッシュの不要な重複を防ぐために、二重引用符の代わりに中括弧で置換テキストを囲む必要があります。置換テキスト\1は、中括弧を使用すると{\1}になり、引用符を使用すると"\\1"になります。

最終引数として変数参照を渡すと、その変数に置換が適用された文字列が格納され、regsubは実行された置換の数を示す整数を返します。Tcl 8.4以降では、最終引数を省略できます。その場合、regsubは置換が適用された文字列を返します。

| クイックスタート | チュートリアル | ツールと言語 |  | リファレンス | 書評 |

| grep | PowerGREP | RegexBuddy | RegexMagic |

| EditPad Lite | EditPad Pro |

| Boost | Delphi | GNU (Linux) | Groovy | Java | JavaScript | .NET | PCRE (C/C++) | PCRE2 (C/C++) | Perl | PHP | POSIX | PowerShell | Python | R | Ruby | std::regex | Tcl | VBScript | Visual Basic 6 | wxWidgets | XML スキーマ | Xojo | XQuery & XPath | XRegExp |

| MySQL | Oracle | PostgreSQL |