プログラマメモ2 - programmer no memo2

せいき表現練習 - 最短一致 2009/06/29

Javaです。正規表現です。わかりづらいですが最短一致です。

以下のようなもんもんがありまして、このテキストからSQLだけとりだしたいわけです。

sql = "
select *
from a
where a.i = ?
";

sql = "
select *
from b
where b.i = ?
";


単純に「sql=」からはじまって「;」でおわってるなぁっていうことがわかります。
sql=.*;

とかしちゃうと、一番最後の「;」までマッチしてしまいますね。
ずばり、これが最長一致です。たぶん。

それだと目的とあわないです。「sql」からはじまって、最初に出現した「;」までマッチさせたいわけですから、ここで最短一致が使えるわけです。

下のように書くようです。
.*?


というわけで、以下Javaコード。DOTALLを忘れずに。
package a;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Test_正規表現_最短一致 {

public static byte[] getBytes(InputStream in) throws IOException {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
try {
int len = 0;
byte[] bs = new byte[8192];
while ((len = in.read(bs)) != -1) {
outputStream.write(bs, 0, len);
outputStream.flush();
}
outputStream.close();
} finally {
in.close();
}
return outputStream.toByteArray();
}

public static void main(String[] args) throws IOException {

Test_正規表現_最短一致 t = new Test_正規表現_最短一致();

String s = new String(getBytes(t.getClass().getResourceAsStream(
"txt最短一致.txt")));
t.a(s);
}

void a(String s) {

Pattern pattern = Pattern.compile("\\s*sql =\\s*\"(.*)\";", Pattern.DOTALL);

Matcher matcher = pattern.matcher(s);
int cnt = 0;
while (matcher.find()) {
System.out.println("*** " + ++cnt);
System.out.println(matcher.group(1));
}

}
}

: