Groovyで特定文字(空白類文字)を含まない部分の長さを調べる

前回のGroovyで特定文字(空白類文字)を含む部分の長さを調べるの逆をする。
matching_lengthを利用してサクっと(いくはずだった。。。)

ソース

def matching_length(str, regexp){
    result = 0
    m = (regexp).matcher(str)
    m.find()
    m.each{ chunk ->
        result += chunk.size()
    }
    return result
}
def unmatching_length(str, regexp){
    println str.length() - matching_length(str, regexp)
}

/* 空白類文字以外は何文字か? */
println unmatching_length("abc d eee ff\n", ~/\s/)
println unmatching_length("abc d eee ff", ~/\s/)
println unmatching_length("", ~/\s/)
// ※空白が12個書いてある
println unmatching_length("            \n", ~/\s/)
println unmatching_length("            ", ~/\s/)

/* 「も」以外は何文字か? */
println unmatching_length("すももももももももものうち", ~/も+/)

結果

ERROR groovy.lang.MissingMethodException: No signature of method: groovysh_evaluate.matching_length() is applicable for argument types: (java.lang.String, java.util.regex.Pattern) values: [abc d eee ff
, \s]
        at groovysh_evaluate.unmatching_length (groovysh_evaluate:4)
        at groovysh_evaluate.run (groovysh_evaluate:2)
        ...

MissingMethodException???

インタフェースの型を明示してみる。

def matching_length(str,java.util.regex.Pattern regexp){
    result = 0
    m = (regexp).matcher(str)
    m.find()
    m.each{ chunk ->
        result += chunk.size()
    }
    return result
}

def unmatching_length(str,java.util.regex.Pattern regexp){
    println str.length() - matching_length(str, regexp)
}

/* 空白類文字以外は何文字か? */
println unmatching_length("abc d eee ff\n", ~/\s/)

結果

ERROR groovy.lang.MissingMethodException: No signature of method: groovysh_evaluate.matching_length() is applicable for argument types: (java.lang.String, java.util.regex.Pattern) values: [abc d eee ff
, \s]
        at groovysh_evaluate.unmatching_length (groovysh_evaluate:4)
        at groovysh_evaluate.run (groovysh_evaluate:2)
        ...

あら・・・変わらず。

呼び出すときにもキャストしてみる

def matching_length(str,java.util.regex.Pattern regexp){
//    println regexp.getClass().getName()
    result = 0
    m = (regexp).matcher(str)
    m.find()
    m.each{ chunk ->
        result += chunk.size()
    }
    return result
}

def unmatching_length(str, java.util.regex.Pattern regexp){
//    println regexp.getClass().getName()
    println str.length() - matching_length(str, (java.util.regex.Pattern)regexp)
}

/* 空白類文字以外は何文字か? */
println unmatching_length("abc d eee ff\n", ~/\s/)

結果

ERROR groovy.lang.MissingMethodException: No signature of method: groovysh_evaluate.matching_length() is applicable for argument types: (java.lang.String, java.util.regex.Pattern) values: [abc d eee ff
, \s]
        at groovysh_evaluate.unmatching_length (groovysh_evaluate:4)
        at groovysh_evaluate.run (groovysh_evaluate:2)
        ...

それでもダメだ。。。

クラスを確認してみる

def matching_length(str, regexp){
    println "matching_length() regexp is " +  regexp.getClass().getName()
    result = 0
    m = (regexp).matcher(str)
    m.find()
    m.each{ chunk ->
        result += chunk.size()
    }
    return result
}

def unmatching_length(str, regexp){
    println "unmatching_length() regexp is " + regexp.getClass().getName()
    println str.length() - matching_length(str, regexp)
}

/* 空白類文字は何文字か? */
println matching_length("abc d eee ff\n", ~/\s/)
/* 空白類文字以外は何文字か? */
println unmatching_length("abc d eee ff\n", ~/\s/)

結果

groovy:000> load 044_2_特定の文字を含まない部分の長さを調べる.groovy
===> true
===> true
===> true
matching_length() regexp is java.util.regex.Pattern
4
===> null
unmatching_length() regexp is java.util.regex.Pattern
ERROR groovy.lang.MissingMethodException: No signature of method: groovysh_evaluate.matching_length() is applicable for argument types: (java.lang.String, java.util.regex.Pattern) values: [abc d eee ff
, \s]
        at groovysh_evaluate.unmatching_length (groovysh_evaluate:4)
        at groovysh_evaluate.run (groovysh_evaluate:2)
        ...

java.util.regex.Patternだぞ。
なんで、groovy.lang.MissingMethodExceptionになるんだ???

defをintに変更してみる

int matching_length(str, regexp){
    println "matching_length() regexp is " +  regexp.getClass().getName()

    result = 0
    m = (regexp).matcher(str)
    m.find()
    m.each{ chunk ->
        result += chunk.size()
    }
    return result
}

int unmatching_length(str, regexp){
    println "unmatching_length() regexp is " + regexp.getClass().getName()
    return str.length() - matching_length(str, regexp)
}

/* 空白類文字以外は何文字か? */
println matching_length("abc d eee ff\n", ~/\s/)
println unmatching_length("abc d eee ff\n", ~/\s/)

結果

groovy:000> load 044_2_特定の文字を含まない部分の長さを調べる.groovy
===> true
===> true
===> true
matching_length() regexp is java.util.regex.Pattern
4
===> null
unmatching_length() regexp is java.util.regex.Pattern
ERROR groovy.lang.MissingMethodException: No signature of method: groovysh_evaluate.matching_length() is applicable for argument types: (java.lang.String, java.util.regex.Pattern) values: [abc d eee ff
, \s]
        at groovysh_evaluate.unmatching_length (groovysh_evaluate:4)
        at groovysh_evaluate.run (groovysh_evaluate:2)
        ...

関係ないわな。

unmatching_lengthにも同じ処理を書く

def unmatching_length(str, regexp){
    result = 0
    m = (regexp).matcher(str)
    m.find()
    m.each{ chunk ->
        result += chunk.size()
    }
    return str.length() - result
}

/* 空白類文字以外は何文字か? */
println unmatching_length("abc d eee ff\n", ~/\s/)
println unmatching_length("abc d eee ff", ~/\s/)
println unmatching_length("", ~/\s/)
// ※空白が12個書いてある
println unmatching_length("            \n", ~/\s/)
println unmatching_length("            ", ~/\s/)

/* 「も」以外は何文字か? */
println unmatching_length("すももももももももものうち", ~/も+/)

結果

groovy:000> load 044_2_特定の文字を含まない部分の長さを調べる.groovy
===> true
===> true
9
===> null
9
===> null
0
===> null
===> true
0
===> null
0
===> null
===> true
4
===> null


動いたがこれはスマートじゃない。


全体からmatching_lengthを引けばいいと思ったのだが、そうは問屋が卸さなかった。
甘かったか。

疑問

正規表現(java.util.regex.Pattern)でパラメータで受け取って、
他のメソッドに渡すにはどうすればいいんだ?



最近のキーワード










Groovyの詳細についてはJavadocと以下の書籍を参考にしている。

Groovyイン・アクション
Dierk Konig Andrew Glover Paul King Guillaume Laforge Jon Skeet
毎日コミュニケーションズ
売り上げランキング: 294340


問題自体は以下の書籍のもの。rubyと似てる部分も多いので、ヒントにもなる。
写経でもいいが自分で考えるために他言語の例をGroovyで置き換えてる。

Rubyレシピブック 第2版 268の技
青木 峰郎 後藤 裕蔵 高橋 征義
ソフトバンク クリエイティブ
売り上げランキング: 80467


Groovyイン・アクションを読むならあった方が便利かな。

ブックストッパー

トモエ算盤
売り上げランキング: 614


Rubyレシピブックは「ほんたった」で立ててる