2013年10月21日月曜日

grep -Pで日本語のUnicodeプロパティが使えない件について

Mountain Lionのgrepは-Pオプション(Perl互換の正規表現)をサポートしなくなった。巷ではThe Silver Searcherが流行っているみたいだけど、かたくなにgrep -Pを使い続けるならGNU grepをインストールすればいい。

$ brew tap homebrew/dupes
$ brew install grep

これで-Pオプションは使えるようになったけど、日本語のUnicodeプロパティはマッチしない(-vはパターンの反転なのでマッチしない行が表示される)。

(追記)バージョン2.15でマッチするように修正された。

$ echo "あ" | ggrep -v -P "\p{Hiragana}"
あ

ggrepになっているのはtypoではなくて、コマンド名が衝突しないように、Homebrewがプレフィックスを付けてインストールするため。

GNU grepはPerl互換の正規表現ライブラリであるPCRE(Perl Compatible Regular Expressions)に依存していて、Unicodeプロパティを使う場合はPCREのconfigureで有効にする必要がある。念のためpcretestコマンドで確認してみる。

$ pcretest -C
PCRE version 8.33 2013-05-28
Compiled with
  8-bit support
  UTF-8 support
  Unicode properties support
  Just-in-time compiler support: x86 64bit (little endian + unaligned)
  Newline sequence is LF
  \R matches all Unicode newlines
  Internal link size = 2
  POSIX malloc threshold = 10
  Default match limit = 10000000
  Default recursion depth limit = 10000000
  Match recursion uses stack

有効になっていた。

ここで、pcregrepというコマンドがインストールされていることに気付いたので、試してみたけどやっぱりマッチしない。

$ echo "あ" | pcregrep -v "\p{Hiragana}"
あ

ヘルプを見ると、UTF-8モードを有効にする-uオプションというのがあったので、これを指定してみたらマッチした。

$ echo "あ" | pcregrep -u "\p{Hiragana}"
あ

UTF-8モードについて調べるためman pcreしてみると、non-UTF-8 modeではUnicodeプロパティのテストは255以下のコードポイントに制限されると書いてあったので、GNU grepでもなんとかしてUTF-8モードにする必要がある。さらにドキュメントを読むと、パターンの先頭に(*UTF8)があればUTF-8モードになるとのことなので試してみる。

$ echo "あ" | ggrep -P "(*UTF8)\p{Hiragana}"
あ

できた。だけど英数記号混じりで毎回7文字もタイプするのはだるい。

ということで、grepのソースを編集してしまうことにした。UTF-8モードにするためには、pcre_compile()PCRE_UTF8を渡せばいいようなので、やってみたら期待通りに動くようになった。

diff --git a/src/pcresearch.c b/src/pcresearch.c
index 2994e65..4a62894 100644
--- a/src/pcresearch.c
+++ b/src/pcresearch.c
@@ -45,7 +45,7 @@ Pcompile (char const *pattern, size_t size)
   int e;
   char const *ep;
   char *re = xnmalloc (4, size + 7);
-  int flags = PCRE_MULTILINE | (match_icase ? PCRE_CASELESS : 0);
+  int flags = PCRE_UTF8 | PCRE_MULTILINE | (match_icase ? PCRE_CASELESS : 0);
   char const *patlim = pattern + size;
   char *n = re;
   char const *p;
$ echo "あ" | ggrep -P "\p{Hiragana}"
あ

上記のパッチを適用するようにHomebrewのFormulaを変更するパッチ。

diff --git a/grep.rb b/grep.rb
index 8fe2284..5ec52d7 100644
--- a/grep.rb
+++ b/grep.rb
@@ -36,4 +36,22 @@ class Grep < Formula
     If you do not want the prefix, install using the 'default-names' option.
     EOS
   end
+
+  def patches
+    DATA
+  end
 end
+__END__
+diff --git a/src/pcresearch.c b/src/pcresearch.c
+index 2994e65..4a62894 100644
+--- a/src/pcresearch.c
++++ b/src/pcresearch.c
+@@ -45,7 +45,7 @@ Pcompile (char const *pattern, size_t size)
+   int e;
+   char const *ep;
+   char *re = xnmalloc (4, size + 7);
+-  int flags = PCRE_MULTILINE | (match_icase ? PCRE_CASELESS : 0);
++  int flags = PCRE_UTF8 | PCRE_MULTILINE | (match_icase ? PCRE_CASELESS : 0);
+   char const *patlim = pattern + size;
+   char *n = re;
+   char const *p;

だけど、pcregrepはGNU grepとの互換性が高いようなので、これをそのまま使うのもありな気がする。大きな違いは、BSD grepと同じくパスをオプションの後に置くことと、--include,--excludeを正規表現で指定すること。pcregrep特有のオプションもいくつかある。

2013年5月26日日曜日

デッドハングは大きめのエッジで加重したほうが効果が高い

デッドハングによる指のトレーニング方法を比較した論文を読んでみた。デッドハングはフィンガーボードなどにぶら下がるトレーニングのこと。

López-Rivera, Eva, González-Badillo, Juan José (2012). "The effects of two maximum grip strength training methods using the same effort duration and different edge depth on grip endurance in elite climbers" Sports Technology 5:100-110.

  • 8a以上を登れるクライマーを2群に分けて、それぞれ異なる順序で2種類のデッドハングのトレーニングを行った
  • 2種類のデッドハングとは、18mmのエッジで最大の重りを装着して行う方法(MAWと表記)と、重りは使わずに可能な限り小さなエッジにぶら下がる方法(MEDと表記)
  • MED–MAWグループは4週間のMEDの後にMAWを4週間行った。逆に、MAW–MEDグループは4週間のMAWの後にMEDを4週間行った。
  • 最大筋力、持久力ともにMAW-MEDグループのほうが向上した。ただしp > 0.05。統計学的に変化は認められなかったという結論になるけど、著者によるとこれは標本数が少ないためだとか。
  • 体重の影響を除去すると、最大筋力と持久力、最大筋力の変化と持久力の変化の間には有意な正の相関が認められた
  • 得られたデータはMAW-MEDのほうが効果的であることを示唆している

この研究に至った経緯はだいたい次のような感じ。

  • 先行研究から指の最大筋力とクライミングのパフォーマンスには相関があることがわかっている
  • クライミングでは小さなホールドを持つ能力が必須なので、できる限り小さなホールドにぶら下がることがトレーニングになる(MED)
  • 数々の先行研究から重りを使ったトレーニングが筋力を向上させることがわかっている(MAW)
  • MEDとMAWを比較した研究がまだなかった

トレーニング方法について補足しておくと、デッドハングは最大筋力を鍛えることを目的として行われた。持久力の計測もしているけど、持久力のトレーニングはしていない。ホールディングはセミアーケで、MAWは18mmのエッジに13秒間ぶら下がれる最大の重りをつけて10秒間ぶら下がる。MEDは重りをつけずに13秒間ぶら下がれる最小のエッジに10秒間ぶら下がる。重量またはエッジのサイズは3秒間の余裕を残すようにセットごとに調整する。インターバルは3分。セット数は3から始めて、週ごとに5セットまで増やした。

論文全体としてはMAW-MEDとMED-MAWの比較を行っているわけだけど、MAWとMEDを単体で比較してもMAWのほうが向上した(最大筋力は9.6%と2.1%、持久力は16.69%と11.53%)。この結果に有意差は認められなかったけど、他の研究と比較しつつ、被験者がハイレベルなため9.6%の向上はsignificantと考えることができる、とされている。また、MAWの方が向上した理由は、重りの使用がより大きな筋活性とモーターユニットの動員を起こすためだそうだ。

(追記)strength testは、重りを装着して15mmのエッジに5秒間ぶら下がれる最大重量を計測することで行われた。MEDで使用されたエッジのサイズは5mmから10mmだそうで、3mmしか違わないMAWのほうが結果が向上するのは、特異性の原則から当然のようにも思える。しかし、著者のブログによると、strength testの値と10秒間ぶら下がることのできる最小のエッジのサイズには関連があり、また、12.5mmのエッジでの力の大きさと、7.3mm、5.8mmのエッジでの力の大きさに有意な正の相関を発見した研究も存在する[1]。したがって、実施前にはMEDのほうが向上する可能性も考えられた、ということだと思う。論文では、15mmはthe most representative of the average size of holds used in competitionsとも書かれている。

(追記)5.8mm程度までは、MAWを行うことで、より小さなホールドを持てるようになることが上記から示唆される。しかし、特異性の原則からMEDも行うほうが効果的と考えられ、その際はMAW-MEDの順序で行うのがいい。

(追記)strength testの指標をエッジの小ささにすることはできない。5.8mm以上のエッジでの力の大きさと、2.8mm、4.3mmのエッジでの力の大きさに相関が認められなかったため[1]。

トレーニング期間終了後、脱トレーニングの効果を調べるためレスト期間が設けられた。ただし、デッドハングをやめただけでクライミングは続けていた。2週間のレストで少しだけ強くなって、さらに2週間レストしたら少し弱くなった。

実際にこのトレーニングを行うには、著者のブログで公開されている動画を見るのがわかりやすい。文章でのまとめは次の記事を読むのがいいと思う。

重要な注意点だけここにも列挙しておく。

  • 20mmで40秒、10mmで15秒ができない人はMEDをやる
  • 成長期の子供やクライミング経験2年未満の人はデッドハングをやらない。前者は骨端板が弱く、疲労骨折など怪我の恐れがあるため。後者は腱などの組織がトレーニングに耐えられるほど適応していないと考えられるため。
  • 重りを増やしていって体重の70%程度に達したら、エッジのサイズを小さくして重りを減らす。腰に悪いので。

ちなみに、限界までやらずに3秒間の余裕を残すのも先行研究の結果[2]を踏まえてのことだそうだ。

参考文献

  1. Bourne, R., Halaki, M., Vanwanseele, B., Clarke, J. (2011). "Measuring lifting forces in rock climbing: effect of hold size and fingertip structure." J Appl Biomech 27:40-46.
  2. Izquierdo, M., Ibanez, J., Gonzalez-Badillo, J. J., Hakkinen, K., Ratamess, N. A., Kraemer, W. J., French, D. N., Eslava, J., Altadill, A., Asiain, X., Gorostiaga, E. M. (2006). "Differential effects of strength training leading to failure versus not to failure on hormonal responses, strength, and muscle power gains." J Appl Physiol (1985) 100:1647-1656.