メンチカツには醤油でしょ!!

AWS/Java/Node.js/Spreadsheets/Docker/Jenkins/コミュニティ・勉強会レポを主とした技術系ブログ

java.util.regex.Patternで取ったmatcherのgroupが取得できない

マッチしてるはずなのにIllegalStateException thrown: No match found

たとえば、ある文字列が「画面ID + 定型文字列」であるとして、ここから画面IDを抜き取るという実装を正規表現で行う場合…

jshellで実行してみると

まずは文字列の定義をします。この場合は"Bean"が定型文字列です。

jshell> String actionBeanName = "ScreenIdBean";
actionBeanName ==> "ScreenIdBean"

次に正規表現を定義します。任意の文字列で始まり1文字以上、そして後ろにBeanというパターンです。

jshell> Pattern p = Pattern.compile("^(.+)(Bean)$");
p ==> ^(.+)(Bean)$

matcherメソッドでMatchesオブジェクトを取得しgroup(1)を呼ぶと…なんとエラー!

jshell> p.matcher(actionBeanName).group(1)
|  java.lang.IllegalStateException thrown: No match found
|        at Matcher.group (Matcher.java:645)
|        at Matcher.group (Matcher.java:604)
|        at (#4:1)

確認のためにmatches()を呼ぶもtrue…

jshell> p.matcher(actionBeanName).matches()
$5 ==> true

再度group()を取っても同じくNo match foundエラーです。

一致しているはずなのに取れない理由は…

Matcherのmatches()を呼んだあと、そのオブジェクトでgroupを呼ぶ必要があります。
つまり下記のように、まずmを変数に代入して

jshell> java.util.regex.Matcher m = p.matcher(actionBeanName);
m ==> java.util.regex.Matcher[pattern=^(.+)(Bean)$ region=0,12 lastmatch=]

そのオブジェクトmのmatches()を呼んだ後に

jshell> m.matches()
$7 ==> true

groupを呼ぶと、目的の文字列が抽出できました。

jshell> m.group(1)
$8 ==> "ScreenId"

groupを呼ぶには、一旦matches()を呼ばないといけない

正規表現が必ず一致すると明確な場合、エラーチェックとなるmatches()を省略しがちですが、ここが落とし穴でした。

本来であれば下記のように安全な(?)コーディングを行うので、起こりえないです。

String actionBeanName = "ScreenIdBean";
Matcher m = PATTERN.matcher(actionBeanName);
if (m.matches()) {
String screenId = m.group(1);
// 何かしらの処理.
} else {
// マッチしなかった場合の処理.
}

と、必ずエラーチェックしてたから今まで知らなかったと言い訳しておきます^^;

参考

stackoverflow.com

「JDK 11リリース記念:今知っておくべきJDK 11の重要ポイント」参加

JJUGに参加しました

最初レポートとしてまとめようと思ったのですが、スライドが秀逸すぎたので自分のコメントはちょい足し程度にしました。

JJUGナイトセミナー「JDK 11リリース記念:今知っておくべきJDK 11の重要ポイント」

Java Is Still Free; Javaは今も無償です

冒頭でこちらの資料の紹介がありました。ちょうどこの日に、日本語訳が出たそうです。なぜか未だにすべてのJavaが有償化されると勘違いしている方々が多く、こういうドキュメントが発行されることとなったようです。要約バージョンの部分はわずか2ページですから、よく読んでおきましょう。

docs.google.com

↓ 原文

Java Is Still Free - Google Document

JDK 11リリースなので改めて「新しいJDKリリースモデル解説 (サマリー&アップデート)」 by 伊藤 敬さん

今までのOracle JDKから、Oracle OpenJDK(無償)とOracle JDK(有償)に分かれた話。
そして、OracleJavaサポートのロードマップの話です。
なお先に引用のとおり、Java全体としては他のJDKも選択肢として存在しています。

www.slideshare.net

Java 11 : サポートとVM機能 編 by 久保田 祐史さん

Javaのサポートについての、本当にFrequentlyなFAQが載っています。
そして後半はJava 11のVM機能についてです。

www.slideshare.net

・いつまでに乗り換えるべきか。次のLTSであるJava 17は2021/09とまだ先なので、Java 8の配信サポートが切れる前が良さそう。

・OpenJDKは商用に耐えうる。ただ、そもそもの8⇒11へのマイグレに痛みを伴う可能性あり。

・無償ならAdoptOpenJDK(4年サポート)が良さそう。0 day attackを勘案する場合は、Oracle OpenJDKを選択肢に入れるとよい。

Java 11:APIの変更点 編 by きしだなおきさん

スライドは後日とのことなので、私のメモを取り急ぎ ↓↓

JEP

* JEP 181: Nest-Based Access Control
  - インナークラスの話。nested classではprivateメンバもアクセス可だった。
  - Collections.emptyList() の戻り値に
    .isNestmateOf()
    .getNestHost()
    .getNestMembers()
    などを試してみるとよいとのこと。
* JEP 309: Dynamic Class-File Constants
  - 一般に想像する(?)static finalフィールドではなく、class-file上の定数のこと。
  - Class-File ConstantsにinvokeDynamicのような機構を。
  - CONSTANT_Dynamics
  - バイトコード上の定数の自由度があがる。
  - ただし現時点でのJavaコンパイラでは利用していない。
* JEP 320: Remove the Java EE and CORBA Modules
  - JavaEEとCORBA関連モジュールの削除。
  - JAX-WS -> jaxws-api
  - JAXB -> jaxb-api
  - JAF -> javax.activation-api
  - Common Annotations -> javax.annotation-api
  - JTA -> javax.transaction-api
  をそれぞれ利用すること。
* JEP 321: HTTP Client (Standard)
  - 概要
    - モダンなAPI
    - HTTP/2
    - Reactive
  - 手順としては
    - 基本的な設定をClientで。
    - Requestでリクエストの設定。
    - async対応も。
* JEP 323: Local-Variable Syntax for Lambda Parameters
  - Lambda内の変数でvarが使えるようになり、アノテーションも付けれる。

JEPに載ってないAPIの追加・削除・挙動変更

* APIの追加
  - 文字列関連
    - String.repeat
      "aa".repeat(3) ⇒ "aaaaaa"
    - String.isBlank
      " ".isBlank ⇒ 全角も加味してtrueが返る
    - String.strip /String.stripLeading /String.stripTrailing
      こちらも全角対応。
    - String.lines
      StringのStreamが返る。"LINE1¥nLINE2".lines().count() ⇒ 2
    - Character.toString(int)
        Character.toString(65) ⇒ "A"
  - I/O
    - Files
      - isSameContent, writeString, readString などの小回りの良い便利メソッド追加。
    - null I/O ⇒ dev/nullのようなもの
      - Reader.nullReader()
      - Writer.nullReader()
      - InputStream.nullReader()
      - OutputStream.nullReader()
  - Path.of
    Paths.of が Path.of にも追加された。
  - Util
    - Collection.toArray(IntFunction)
      List.of("aaa").toArray(new String[1]) が
      List.of("aaa").toArray(String[]::new) と書けるようになった。
    - Predicate.not
      filterの否定に利用
        List.of("aaa", "").stream().filter(String::isEmpty).toArray();
      の逆が
        List.of("aaa", "").stream().filter(Predicate.not(String::isEmpty)).toArray();
      と書けるようになった。
    - Optional, OptionalInt, OpttionalLong, OptionalDouble
       - isEmpty
* API削除
  - Thread.destroy
  - Thread.stop(Throwable)
  - javax.security.auth.Policy
* 挙動変更
  - ArrayIndexOutOfBoundsException
    - エラーメッセージが "Index 1 out of bounds for length 0." のようになる。
  - 新元号対応
    - JapaneseDate.of(JapaneseEra.HEISEI, 31, 5, 1);
      でエラーとなる。(そんな平成は無いというエラー)
      JapaneseDate.from(LocalDate.of(2020, 1, 1));
      ⇒ Japanese NewEra 2-01-01
    - Java 12.0.1 (2019/04/25ぐらい?)で反映。

JDK11で修正されたバグ

* var のバグ
  var attrs = List.of("size", 1);
  のようなコードでdebug情報付きの時にコンパイラが落ちてしまうバグの解消。
  原因はObject, Serializable, Comparableなどの複数のinterfaceの型推論がはたらくため。
* Stringの+= のバグ
  s[i++] += "foo"
  のように配列の要素に++を入れつつ+=を行うと、JDK10では
  s[i++] = s[i++] + "foo"
  と解釈されてしまうバグの解消。
* TimSort のバグ
  - Arrays.sort / List.sort / Collections.sort が対象。
  - 67108864以上の要素がある場合の特定のケース。
  ArrayIndexOutOfBoundsExceptionが発生することがあるバグの解消。

Java12で入りそうな機能の話

* JEP 326: Raw String Literals

`
foo
foo
foo
` ⇒ "¥nfoo¥nfoo¥n"

* JEP 325: Switch Expressions
まだ実装されていないらしい。調べた感じだとこんなの↓

switch (day) {
    case MONDAY                       -> System.out.println("Off");
    case TUESDAY, WEDNESDAY, THURSDAY -> System.out.println("Work");
    case FRIDAY                       -> System.out.println("Drink");
    case SATURDAY, SUNDAY             -> System.out.println("Holiday");
}

* String.indent / align
Raw String LiteralsよるStringの便利メソッドの追加.

`
foo
foo
`.align(0) ⇒ "foo¥nfoo¥n"

さいごに

Javaは今も無償です。

「Puppeteer入門」という本を執筆しました

Puppeteer入門 という本を執筆しました

先日こっそり触れましたが、Puppeteerの入門書が秀和システムから出版されました。表紙は漫画家の鶴田謙二さん。
表紙目当てで買って頂ける方もいらっしゃるようです。
Node.jsの知識がなくてもWebスクレイピングができるようになれるよう書きました。

www.shuwasystem.co.jp

Amazonのリンクはコチラ

ざっくり内容

・Puppeteerを使い始めるまでの色々な環境構築
JavaScript や Node.jsの書き方
・ブラウザ操作の自動化 (要素の特定、要素への入力など)
・実践例いろいろ
・テスト自動化への適用やデバッグ

と、だいたいこんな感じの流れになってます。

読んでいただいた方々の声

Amazonのカスタマーレビューより

Puppeteerを使いこなしたかったので買ってみましたが、大当たり!
これは色んな人にお勧めしたい本です。
機能解説に止まらず、色んな角度から「自動処理」の考え方を教えてくれる内容でした。

初心者にもわかりやすいように環境構築方法が丁寧に書いてあるし、
(僕は初心者ではないので、本当に初心者向きかは保証できませんが!)
すぐに使える実用的なサンプルプログラムも豊富だし、
コラムとか本文の節々に書かれている著者の体験談がとても面白く、
中〜上級者が読んでも、深みを感じられる内容だと思います。

とにかく「自動化大好きなんだろうな〜。かなり試行錯誤を繰り返して来たエッセンスなんだろうな〜」
っていう著者の熱い想いがかなり伝わってきました。

www.amazon.co.jp

これは本当に嬉しい!!m(_ _)mm(_ _)mm(_ _)m
高い評価もさることながら、特に 自動化が大好き ということを感じとって頂けて何よりです。

Twitter

感謝×2です。拾いきれてなかったらスミマセン

書店にもこっそり見にいったり

f:id:ryoichi0102:20180922163124j:plain

f:id:ryoichi0102:20180922163130j:plain

嬉しい…しみじみ。自分の力ではありませんが良い位置。店舗によっては置いてあったりなかったり一喜一憂。
我が子が買ってくれた方の役に立ってほしい。

締めのひとこと

初心忘れるべからず。