検索関連メモ
正規表現メタキャラクター
「.」 | 任意の一文字にマッチ | 改行以外のあらゆる文字 |
[] | []内の文字のどれか | [^A-Za-z]はアルファベット以外 |
? | 直前の正規表現が0か1回現れるものにマッチ | “e-?mail” emailかe-mail |
* | 直前の正規表現が0回以上の任意繰り返し | “abc*” ab,abc,abcc,abcccなど |
+ | 直前の正規表現の1回以上の繰り返し | |
^ | 正規表現の先頭に書いて、行頭にマッチ | 先頭以外に書いた場合は^自身にマッチ |
$ | 正規表現の末尾に書いて、行末にマッチ | 末尾以外は$自身にマッチ |
\ | メタキャラクタの特別な意味を消す | 「\.」は「.」にマッチ |
\( \) | 正規表現をグルーピング | マッチした文字列の一部を取り出せる |
\| | 「または」の意味 | |
\数字 | グルーピングした「数字番目」の部分取り出し | |
\< \> | 単語の先頭と単語の末尾にマッチ | |
\w \W | 単語を構成する文字や数字にマッチ。後者はそれ以外 | |
\sC \SC |
re-builderによる確認
M-x re-builderにより、正規表現の確認をすることが出来る。
replace-match の使い方
eplace-match REPLACEMENT &optional FIXEDCASE LITERAL STRING SUBEXP
最後の探索で一致したバッファ内(あるいは文字列STRING)のテキストをREPLACEMENTで置き換える。
バッファで最後に探索を行った場合には、STRINGに`nil’を指定すると、`replace-match’はバッファを編集することで置換を行い、置換したテキストの末尾にポイントを置き`t’を返す。
文字列で探索した場合には、STRINGに同じ文字列を渡すこと。そうすると、`replace-match’は新たな文字列を構築することで置換を行って新たな文字列を返す。
(while (< aa sentakumogyo) (setq hha (nth aa gmonhha)) (if (string-match "\\\\hha" hha) (progn (setq hha (replace-match rr nil nil hha)) (insert hha) (insert "\n\n"))) (setq aa (1+ aa)))
正規表現 最短一致
次のように括弧が2つ続けてある場合、普通の方法だと、[A]の様になる。[B]のようにするには、少し工夫が必要である。
(T- ) (t- ) driving because you have to go a long way.
[A] (T- ) (t- ) driving because you have to go a long way. [B] (T- ) (t- ) driving because you have to go a long way.
正規表現のコード
(string-match "(.*)" dbb) ; [A]
(string-match "([^)]+)" dbb) ; [B] 「)」以外が続いた後「)」
replace-regexp-in-stringを使う方法
この例では、変数aaに<>が複数個あった場合、それを全部入れ替えている
(setq mc (length gmon)) (while (< bb mc) (setq aa (nth bb gmon)) (while (string-match "<>" aa) (progn (setq gkicnt (1+ gkicnt)) (setq aa (replace-regexp-in-string "<>" "\\\\hha" aa)))) (setq gmonhha (cons aa gmonhha)) (setq bb (1+ bb)))
正規表現の具体例
「\begin{enumerate}」の位置を検索したい
(defun conqure-parbox ()
"最初の\enumerateの位置を見つける"
(interactive)
(let (a b bbb ccc (cnt 0))
(goto-char (point-min))
(if (re-search-forward "\\\\begin{enumerate}" nil t)
(progn
(具体的な処理を記述
))
(error "begin{enumerate}が見つかりません"))))
2つ以上続く空白をひとつにする
;;;
(defun cc-kuhaku2 ()
"2つ以上連続する空白を1つにする"
(interactive)
(let ((cnt 0))
(goto-char (point-min))
(while (re-search-forward " +" nil t)
(progn
(replace-match " ")
(forward-char 1)
(setq cnt (1+ cnt))))
(message "連続する空白%d回処理しました。" cnt)
(sit-for 3)
(goto-char (point-min))))
行頭から「% 日本語訳が続きます」や「* ここはコメントです」の「% 」、「* 」、「** 」(*が連続する)を除きたい場合の例
グルーピングして、最初(「% 」,「* 」、「** 」)をグループ1,残りをグループ2としている。マッチした部分のグループ2だけを取り出している
(defun pybun-elisp-4taku-card-ura-jj-com () "4択裏面の日本語、コメント処理" (let (aa) (cond ((string-match "\\\(^% +\\\)\\\(.*\\\)" uragyo) (setq uragyo (substring uragyo (match-beginning 2) (match-end 2)))) ((string-match "\\\(\\\*+ +\\\)\\\(.+\\\)" uragyo) (setq uragyo (substring uragyo (match-beginning 2) (match-end 2)))) (t (error "コメント行のフォーマットが違います %s" uragyo)))))