Mazn.net

やってみて 調べてみて 苦労しなけりゃ 箱は動かじ

Cのコメント部分を正規表現で検索@vim

      2013/07/15

ソースコードを機械的に解析する際、コメントが邪魔だったりします。

viでコメント部分を削除しようとして、正規表現で以下のようにコメント部分を検索するとします。

\\/\\*.*\\*\\/

これは、/*で始まり、任意の文字列”.*”が続いた後に、*/で終わる部分にマッチしますので、

/* hoge */

というコメント部分にもちろんマッチしますが、実は最も長い部分にマッチするため、

/* hoge */ int a = 0; /* hoge */

は、int a =0; も含めてマッチしてしまいます。よって、/* と */の間にはコメントの閉じである*/がこないことを正規表現で表現する必要があります。

ここで、少し考え方が難しくなります。 じつは正規表現で否定を表現する場合、[^abc]と表現できますが、これはabcという文字列がこないという意味ではなくて、aかbかcがこないという意味なので目的にあいません。

よって、任意の文字”.”を[^*/]に置き換えた場合は、*または/ではないという意味なので、

\\/\\*[^*\/]*\\*\\/

という正規表現は、

/* hoge/hoge */

という”/”を含んだコメントにマッチしなくなってしまいます。

では”*/”という文字列ではない という表現はどう表現すればよいのでしょうか。

正規表現では文字列否定専用の表現はありません。そこで”/” 以外の文字」と「直前が “*” 以外の “/”」と考えます。

これを正規表現と表すと

\\([^\\/]\\|[^*]\\/\\)*

となり、/* と */の条件も付け加えると

 \\/\\*\\([^\\/]\\|[^*]\\/\\)*\\*\\/

となります。

さらに、/* */は途中に改行が入る可能性があります。”.”は改行にはマッチしないので、改行の表現である”\n”をマッチの条件に追加して

\\/\\*\\([^\\/]\\|[^*]\\/\\|\\n\\)*\\*\\/

となり、なんとか動いてくれたようです。複雑ですね~

これを使用することで、コメントの中にある文字列を探すことも可能になります。

上記を整理すると、Cにおいて 以下が改行を考慮した*/以外の文字列を示しているので

\\([^\\/]\\|[^*]\\/\\|\\n\\)*

コメント内の文字列を探すには、探す文字列の前後にこの表現があればよいことになります。つまりhogeを探すならこのようになります。

\\/\\*\\([^\\/]\\|[^*]\\/\\|\\n\\)*hoge\\([^\\/]\\|[^*]\\/\\|\\n\\)*\\*\\/

なお、上記で説明した正規表現は、実はprintf などの文字列内にある/* */もマッチしてしまいます。他にも条件によっては動作がおかしくなる可能性があるので注意してくださ。

文字列を含まないというのを汎用的に表現すると、もっと難しく、さらにメモリ消費が激しいようです。参考サイトには文字列を含まない正規表現を自動生成してくれるJavascriptもありますが、maznの環境では動作が重く、実用に耐えられませんでした。

参考
http://blog.livedoor.jp/froo/archives/50581540.html
http://funcchan.blog16.fc2.com/blog-entry-39.html
http://www.kt.rim.or.jp/~kbk/regex/regex.html

 - IT技術, プログラミング ,

336px

Message

メールアドレスが公開されることはありません。

  関連記事

no image
プログラミング言語のベンチマーク

プログラミング言語のベンチマークサイトを発見 http://shootout.a …

k3dを使ってマルチノード構成のKubernetesを一瞬で構築する

一昔前までは、Kubernetesの学習環境を手元に作るには、それなりに手間がか …

no image
rdesktopの改造@Debian etch

LinuxからWindowsのリモートデスクトップに接続するコマンドです。 De …

no image
BeckyからThunderbirdへのデータの移行

BeckyからThunderbirdへのデータの移行はネット上に多くの事例が掲載 …

no image
VirtualBox 5で、USBメモリ全体をディスクとして使う@Windows 10

管理者権限でWindowsのコマンドプロンプトを起動し、以下のようにUSBメモリ …

no image
QRコードスキャナーのようなカメラ使うアプリが起動しない@Galaxy S (2.2)

標準のカメラアプリは正常に動作するのに、QRコードスキャナやFxCamera と …

no image
TracのDBのスキーマとチケットレポート作成 @ Trac 0.10.3 on Debian Etch

Tracのチケット のレポートを作成するには、TracのDBのスキーマをある程度 …

no image
dnsmasqでDNSサーバを立ててWindowsから参照させる

Linuxサーバ上にdnsmasqで DNSサーバ立てて、自宅内のサーバの名前解 …

no image
qcow2のディスクイメージをマウントして編集する@Ubuntu12.04

KVMなどで使われているqcow2形式のディスクイメージは、単純なディスクイメー …

Go言語の構造体をネスト

最近GO言語を勉強していて、ネスト(入れ子)された構造体のフィールドにアクセスす …