必要レベル
- 正規表現を使ったことがある。
- メタキャラクタという物をいくつか知っている
xyzzy上の正規表現の文法
基本的な正規表現(grepやsedで使われている)は使えるようです。
.+*?()[]^$|や \nなどのエスケープ記号は対応しています。
POSIXのような :digit:などや、Perlの拡張正規表現である \d等の形式は対応していません。
また グルーピングは \(とエスケープが必要になります。
refer:
xyzzyの正規表現の表記(wiki) | 正規表現(wikipedia)
ファイラーによる 正規表現活用例(rename)
リファレンス(wiki) >
Type > Tips >
Emacs 互換ではない正規表現は結構あるのでしょうか?
正規表現の種類
4パターンに分けて正規表現文字とその意味を説明します。
- 繰り返し
- 文字種系
- パターン系
- 位置系
なので、使い方は
(位置) (文字種 or パターン)(繰り返し)の並び順になると思います。
(A).繰り返し
? | 01234567 | 任意の1文字(あり(1文字) or なし(0文字)) |
+ | @0+
=>@0000123
=>@0123
=>NG:@123
| 存在文字数(1文字以上) |
* |
@0*
=>@00000123
=>@123
|
直前の文字orグループがあってもなくても良い(0文字も含む) |
@\{M,N\} | |-M文字-|
|-----N文字-----| ...
..@@@@...@@@@... | M回~N回(MまはたNのどちらかを省略した場合、その方向に無制限) |
@\{L\} | |-L文字-|
...@@@@@... | 直前の文字orグループのL回のみ |
繰り返しに?をつけると 最長マッチではなく、最短マッチとなります。
e.g. ??、*?、+?、\{\}?、\(?:\)など
Version 0.2.1.186
(B).文字種
文字のメタ情報を表す正規表現
. | 01234567 | 任意の1文字 |
\w+ | 活01234567luckey## | 英数字の1文字 |
\W+ | 活01234567luckey## | 英数字以外の1文字 |
\+ | +01234567 | 正規表現文字そのもの1文字 |
\s | point-max | シンタックス文字
\sw \s \s( \s. など |
\S | point-max__"pop" | シンタックス文字以外 |
\_s | point_max | シンボル文字 |
\_S | point_max__"life" | シンボル文字以外 |
ざっくり説明すると、
Javaのシンボル: 変数に使えるもの
Javaのシンタックス:ソースに書ける文字全部(空白とかは除くのかな)
だから言語によってsymbolの指すものは少し違う。詳しくはリファレンスや java.lなど参考に!
シンタックスコードはこちらが参考になります。
refrence:skip-syntax-spec-forward
|日記(Ultima Thule)
(C).パターン
[ ... ] | | 文字のorマッチ,文字群の無名定義
(単語のorマッチの場合()を使う) |
[123]+ | 活01234567luckey## | 括弧内の文字パターン群 |
[0-9]+ | 活01234567luckey## | 括弧内の文字範囲パターン群 |
[^123]+ | 1234567luckey## | 括弧内の文字以外パターン群 |
\( ... \) | | 単語の定義(名前は グルーピング順序で\1 ,\2と後方参照可能) |
\(?:regexp\) | | 単語後方参照不可 |
\| | \(090\) | \(080\) |
=>OK:09011 =>NG:122128 | 前後のどちらかがあればマッチ |
(D).位置系
位置のメタ情報を表す正規表現
\` | バッファ先頭 |
|
^ |
(<- 行頭) | | (行末 ->) |
$ |
|
\b |
[WORD] |
\B |
単語の境界 |
\< | \> |
単語の開始・終了 |
\_b |
\_B |
シンボルの境界 |
\_< | \_> |
シンボルの開始/終了位置 |
\' | バッファ最後 |
正規表現を動かしてみる!!
キーワード指定に正規表現を使った例 ,
ファイラーのファイル置換に正規表現を使った例,
基礎
;基礎
a
'a' という1文字にマッチ
a.b
"ab" or "adb" or "a7b" .... 等 任意の文字
(string-match "a.b" "a8b")
0
(string-match "a.b" "a&b")
0
a?xyz
"xyz" "axyz" など 直前の文字が0か1文字の時
a+
"a" "aaaaaaaaa" など 1文字以上
ba*
"b" "ba" "baa" "baaaaaaaa" など0文字以上
[Xx]yzzy
"Xyzzy" or "xyzzy" []の中はそのうちどれか
[^x]yzzy
[^]の場合その要素以外(補集合)
(string-match "[^x]yzzy" "yzzy")
nil
(string-match "[^x]yzzy" "xyzzy")
nil
(string-match "[^x]yzzy" "ayzzy")
0
[0-9]abc
[]の中の - は 連続 この場合[0123456789]と同じ
[]の中では - [ ] ^ *など 場所によって働かない場合もあるので注意
(string-match "[0-9]abc" "7abc")
0
(string-match "[0-9]abc" "0abc")
0
(string-match "[0-9]abc" "Aabc")
nil
\
メタキャラクタそのものを指定したい場合直前に入れる(エスケープするという)
(string-match "\]a" "]a")
0
(string-match "\*a" "*a")
0
\t
特別な文字。この場合タブ文字(\nなど)
(string-match "\t" " ")
0
\{m\}
\{m,\}
\{,n\}
\{m,n\}
m回(m回以上、n回以下、m回からn回)繰り返し。
本当は上のように描くが エスケープされて "\{" が "{"になってしまうためかきのようにエスケープ記号をエスケープする。
また "\\{" "\{"になる。 "\\\{" は "\\" "\{"に分かれて "\{"と解釈される
このように文字列のエスケープと正規表現のごった煮のミスがよくある
(string-match "a\\{3\\}" "aa")
nil
(string-match "a\\{3\\}" "baaa")
1
(string-match "a{3}" "aaa")
nil
(string-match "a\\\{3\\\}" "aaa")
0
(string-match "ba\\{1,3\\}b" "baaaab")
nil
|
ちと休憩。、、、、、
正規表現の特殊記号
;位置など
^
先頭
$
最後
行レベルで考えますので、行頭や行の最後の位置を明示します。
(string-match "^abc" "abc")
0
(string-match "^abc" "kabc")
nil
(string-match "abc" "kabc")
1
(string-match "^abc$" "abc")
0
(string-match "^abc$" "abc;")
nil
\\<
\\>
単語の最初と最後にマッチ
(string-match "\\<abc\\>" "abc")
0
(string-match "\\<abc\\>" "jabc")
nil
(string-match "abc" "jabc")
1
\\(
\\)
グルーピング
\\1
グルーピングしてマッチした順番
後でさっき見た物を再利用できます。
(string-match "\\(abc\\)\\1" "Zabcabc")
1
(string-match "\\(abc\\)\\1" "abc")
nil
回文みたいなのとか
(string-match "\\(.\\)\\(.\\)\\(.\\)\\3\\2\\1" "abccba")
0
(string-match "\\(.\\)\\(.\\)\\(.\\)\\3\\2\\1" "abcabc")
nil
|(縦棒)
どちらか
(string-match "maru\\|batu" "maru")
0
(string-match "maru\\|batu" "batu")
0
|
ちと休憩。、、、、、
息継ぎおば
;特殊意味
\w
英数字
\W
英数字以外
_(under-bar)はだめみたい
\tと根本的に意味が違うことに注意
(string-match "a\\wc" "abc")
0
(string-match "a\\wc" "a0c")
0
(string-match "a\\wc" "a-c")
nil
(string-match "a\\Wc" "abc")
nil
(string-match "a\\Wc" "a0c")
nil
(string-match "a\\Wc" "a-c")
0
(string-match "\\sw" "abc")
0
(string-match "\\sw" "123")
0
(string-match "\\s " " ")
0
(string-match "\\s " "abc")
nil
(string-match "\\sk" "カナ")
0
(string-match "\\sk" "かな")
nil
(string-match "\\_s+" "abc-abc")
0
(string-match "\\_s+" "0abcabc")
0
(string-match "\\_s+" "abc_abc")
0
(string-match "\\_S+" " ##")
0
(string-match "\\_S+" "abc")
nil
(string-match "\\w+" "abcabc")
0
|
正規表現活用サンプル
それでは少し現実的な正規表現の複合例を示します。
拡張子が zip かどうか
(string-match "\.zip$" "achive.zip")
6
(string-match "\.zip$" "achive.zip.scr")
nil
200?年にマッチ
(string-match "200[0-9]" "2001/2/2")
0
ある日付フォーマットにマッチ
(string-match "[0-9]\\{4\\}/[0-9]\\{,2\\}/[0-9]\\{,2\\}" "2001/2/2")
0
(string-match "[0-9]\\{4\\}/[0-9]\\{,2\\}/[0-9]\\{,2\\}" "1997/04/31")
0
タグの閉じ括弧に対応
正確にやるにはもっと大変。
(string-match "<[^>]+>.*\\(</[^>]+>\\)?" "<h1></h1>")
0
(string-match "プリンター\\|プリンタ" "私のプリンター")
2
(string-match "プリンター?" "どこののプリンタ")
4
;
|
正規表現についてはこんな感じです。
グルーピングの例として、
ファイラーのファイル置換に正規表現を使った例,
正規表現でlispを書くときに、知っておくと便利な Tips
meta文字の クォート
(regexp-quote "^head\\.left[0-9]*%")
"\\^head\\\\\\.left\\[0-9]\\*%"
|
|