gnuplotの便利な文字列関数

ここでは、gnuplot 4.2以降で使える、幾つかの便利な文字列関数を紹介します。

便利な文字列関数

strsubst(str,target,subst)
文字列strの中の文字列targetを全て文字列substに置換する

strsubst(str,target,subst)関数は、文字列strの中の文字列targetを文字列substに置換する関数です。例えば、strsubst("this is a test string", "test", "funny")は一番目の文字列のtestfunnyに置換して、this is a funny stringという文字列を返します。

例えば、enhancedモードでアンダーバー(_)を含むファイル名(例えばtest_20080701.dat)をplot titleとして出力したいとき、title "test_20080701.dat"としたのではアンダーバーが下付き文字のための記号と解釈されてしまい、グラフ上ではtest20080701.datのように表示されてしまいます。この場合、title strsubst("test_20080701.dat", "_", "\\_")とするとアンダーバー_が\\_にエスケープされるためグラフ上で正しく表示されます。

この関数は以下のようにして実装できます。2017.02.02 gnuplot 5.0以降?では部分文字列を取得するstr[]がなぜか使えなくなっているようだったので、それを回避するように改良しました。

# strの中でtargetよりも前の部分文字列を返す
substr_str_before(str, target)=substr(str, 1, strstrt(str,target)-1)
# strの中でtargetよりも後の部分文字列を返す
substr_str_after(str, target)=\
     substr(str, strstrt(str,target)+strlen(target), strlen(str))
# strの中でindexより後の部分の文字列を返す
substr_after(str, index) = substr(str, index, strlen(str))
# strの中でindexより前の部分の文字列を返す
substr_before(str, index) = substr(str, 1, index)
# 再帰表現を利用して、strのindexより後の文字列のtargetをsubstに全て置換する
strsubst_sub(str, index, target, subst)=\
     strstrt(substr_after(str,index),target)==0 ? str :\
     strsubst_sub( substr_before(str, index-1) . substr_str_before(substr_after(str,index),target) . \
     subst . substr_str_after(substr_after(str,index),target),\
     index+strstrt(substr_after(str,index),target)+strlen(subst)-strlen(target),\
     target, subst)

# strの中のtargetをsubstに置換する
strsubst(str, target, subst)=strsubst_sub(str,1,target,subst)
strstrlt(str,target)
文字列strの中でtargetの最後に出てくる場所を返す

strstrlt(str,target)は文字列strの中で文字列targetの出てくる位置(targetの最初の文字がstrの中で何文字目か)を返すのですが、targetが複数存在する場合はもっともstrの末尾に近い位置を返します。

例えば、strstrlt("abcdeabcde", "de")は第一引数の文字列の中の4字めと9字目にdeという文字列があるので、そのうちの大きい方である9を返します。

この関数も以下のように再帰表現を利用して実装することができます。2009.03.07 下の例で関数max(x,y)が定義されていなかったので、追加しました。2017.02.02 gnuplot 5.0以降?では部分文字列を取得するstr[]がなぜか使えなくなっているようだったので、それを回避するように改良しました。

#大きい方の値を返す関数を補助的に定義
max(x,y)= ( (x) > (y) ) ? (x) : (y)
# strのindexより後の文字列の中でtargetが最後に出てくる場所を返す
strstrlt_sub(str,index,target)=(strstrt(substr_after(str, index),target)==0 ? \
     max(index-strlen(target),0) : \
     strstrlt_sub(str, index-1+strstrt(substr_after(str, index),target)+strlen(target),target))
# strの中でtargetが最後に出てくる場所を返す
strstrlt(str,target)=strstrlt_sub(str,1,target)
dirname(path)
文字列pathからディレクトリ名を返す。

関数dirname(path)は文字列pathからディレクトリ名を返します。

この関数は上記のstrstrlt関数を利用して実装できます。

# pathからディレクトリ名を返す。
dirname(path)=strstrt(path, "/")!= 0 ? substr(path, 1, strstrlt(path,"/")) : ""
remdirname(path)
文字列pathからディレクトリ名を消したものを返す。

関数remdirname(path)は文字列pathからディレクトリ名を消したもの、すなわち全てのスラッシュ/よりも後の部分の文字列を返します。

この関数も上記のstrstrlt関数を利用して実装できます。

# pathからディレクトリ名を消したものを返す。
remdirname(path)=substr(path,strstrlt(path,"/")+1,strlen(path))
remext(path)
文字列pathから拡張子を消したものを返す。

関数remext(path)は文字列pathから拡張子を消したものを返します。

この関数も上記のstrstrlt関数を利用して実装できます。

# filenameからexentionを消したものを返す
remext(filename)=strstrt(filename, ".")==0 ? filename : \
                 substr(filename,1,strstrlt(filename, ".")-1)

loadする用のファイル

上記の関数を以下のようにまとめてファイルに保存しておき、必要に応じてloadして使うと便利です。

# strの中でtargetよりも前の部分文字列を返す
substr_str_before(str, target)=substr(str, 1, strstrt(str,target)-1)
# strの中でtargetよりも後の部分文字列を返す
substr_str_after(str, target)=\
     substr(str, strstrt(str,target)+strlen(target), strlen(str))
# strの中でindexより後の部分の文字列を返す
substr_after(str, index) = substr(str, index, strlen(str))
# strの中でindexより前の部分の文字列を返す
substr_before(str, index) = substr(str, 1, index)
# 再帰表現を利用して、strのindexより後の文字列のtargetをsubstに全て置換する
strsubst_sub(str, index, target, subst)=\
     strstrt(substr_after(str,index),target)==0 ? str :\
     strsubst_sub( substr_before(str, index-1) . substr_str_before(substr_after(str,index),target) . \
     subst . substr_str_after(substr_after(str,index),target),\
     index+strstrt(substr_after(str,index),target)+strlen(subst)-strlen(target),\
     target, subst)

# strの中のtargetをsubstに置換する
strsubst(str, target, subst)=strsubst_sub(str,1,target,subst)


#大きい方の値を返す関数を補助的に定義
max(x,y)= ( (x) > (y) ) ? (x) : (y)
# strのindexより後の文字列の中でtargetが最後に出てくる場所を返す
strstrlt_sub(str,index,target)=(strstrt(substr_after(str, index),target)==0 ? \
     max(index-strlen(target),0) : \
     strstrlt_sub(str, index-1+strstrt(substr_after(str, index),target)+strlen(target),target))
# strの中でtargetが最後に出てくる場所を返す
strstrlt(str,target)=strstrlt_sub(str,1,target)


# pathからディレクトリ名を返す。
dirname(path)=strstrt(path, "/")!= 0 ? substr(path, 1, strstrlt(path,"/")) : ""

# pathからディレクトリ名を消したものを返す。
remdirname(path)=substr(path,strstrlt(path,"/")+1,strlen(path))

# filenameからexentionを消したものを返す
remext(filename)=strstrt(filename, ".")==0 ? filename : \
                 substr(filename,1,strstrlt(filename, ".")-1)