見出し画像

Tera Termマクロで正規表現を使う方法

TeraTermマクロはwaitregexなどいくつかのTTLコマンドで正規表現を使うことができます。正規表現により、より柔軟なマクロを書くことができるようになります。


正規表現とは

正規表現とは文字列の集合をひとつの文字列で表現するものです。たとえばアルファベットの集合なら[a-zA-Z]と表現する事ができます。

このようにある文字列をひとつの文字列で表現する事により柔軟に特定の文字列にマッチさせる事ができるようになります。

正規表現に対応したTTLコマンド

  • strmatch

  • strreplace

  • waitregex

TeraTermマクロの正規表現

TeraTermマクロでは「鬼車」という正規表現ライブラリを使用しています。TeraTermマクロで正規表現を使いこなすためには、この鬼車の使い方を熟知する必要があります。

正規表現の使用例

それでは、せっかくなので実用的な正規表現例をご紹介します。

Cisco機器のログ取得でうまくマッチしない!

という例はよく目にします。これは正規表現が甘いためです。

たとえば show running-config を実行したとします。そういう場合、どのような正規表現を使うか。waitregexを使うと次のような感じです。

waitregex "Switch"

これは一見うまく行くように見えます。しかし、show running-configには次のような文字列が存在します。

 hostname Switch

さきほどの正規表現だと上記の文字列にマッチしてしまいますね。このように単純にホスト名だけでマッチさせると意図しない場所でマッチします。

Cisco機器の場合、ホスト名を「Switch」とすると次のようなプロンプトが存在します。

  • Switch>

  • Switch#

  • Switch(config)#

  • Switch(config-line)#

  • Switch(config-if)#

  • Switch(config-if-range)#

  • Switch(config-vlan)#

  • Switch(vlan)#

他にもありますが、ここでやめておきましょう。このように様々な文字列をすべて調べてwaitregexを使う、というのは現実的ではありません。しかし、このような様々な文字列でも、正規表現ならばひとつの文字列で表現できます。正規表現を使う場合は文字列のパターンを探します。

文字列パターンを探す

Cisco機器のプロンプトには次のようなパターンがあります。

  • ホスト名に続いて「>」もしくは「#」

  • ホスト名に続いて「(config)#」

  • ホスト名に続いて「(config-アルファベット)#」

  • ホスト名に続いて「(config-アルファベット-アルファベット)#」

  • ホスト名に続いて「(vlan)#」

正規表現の文字列作成

まず最初にホスト名に続いて「>」もしくは「#」のパターンを書きます。

^Switch[>#]$

行頭が「Switch」、その後に「>」もしくは「#」があり、続いて行末がある場合にマッチします。

次は「(config)」がある場合を検討します。

^Switch¥(config¥)[>#]$

上記の正規表現でも良さそうに見えますが「(config)」がないとマッチしません。ですので「(config)」は有っても無くても良いよ、という意味の「?」を使います。

^Switch(¥(config¥))?[>#]$

だいぶそれらしくなりました。「(...)?」の部分は有っても無くても良いので、「Switch>」「Switch#」「Switch(config)#」にマッチします。

このように「?」を使うと有っても無くても良いという意味になるので「config」「config-アルファベット」「config-アルファベット-アルファベット」「vlan」すべてにマッチさせるためには、次のような正規表現を使います。

regexstr = "^Switch(([a-z-]+))?[>#]"

さらにホスト名部分(Switch)も正規表現に変えてみます。

regexstr = "^[a-zA-Z0-9]+(([a-z-]+))?[>#]"

この正規表現が実際にマッチするのか、テスト用のマクロを書きました。

; テスト用文字列
strdim str 9
str[0] = "Switch>"
str[1] = "Switch#"
str[2] = "Switch(config)#"
str[3] = "Switch(config-line)#"
str[4] = "Switch(config-if)#"
str[5] = "Switch(config-if-range)#"
str[6] = "Switch(config-vlan)#"
str[7] = "Switch(vlan)#"
str[8] = "hostname Switch"

; 正規表現
regexstr = "^[a-zA-Z0-9]+(\([a-z\-]+\))?[>#]"

for i 0 8
	strmatch str[i] regexstr
	if result == 0 then
		sprintf2 msg "マッチしない\n%s" str[i]
		title = "マッチしない"
	else
		sprintf2 msg "マッチした!!\n%s" str[i]
		title = "マッチした!!"
	endif
	strspecial msg
	messagebox msg title
next

どの文字列にマッチして、どの文字列にはマッチしないのか実際に試してみてください。

この記事が気に入ったらサポートをしてみませんか?