質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
HTML5

HTML5 (Hyper Text Markup Language、バージョン 5)は、マークアップ言語であるHTMLの第5版です。

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

正規表現

正規表現とは特定の文字列によるパターンマッチングを行う際に用いられる宣言型プログラミングです。

Q&A

解決済

2回答

2593閲覧

正規表現 マッチした文字列の取得

an6

総合スコア20

HTML5

HTML5 (Hyper Text Markup Language、バージョン 5)は、マークアップ言語であるHTMLの第5版です。

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

正規表現

正規表現とは特定の文字列によるパターンマッチングを行う際に用いられる宣言型プログラミングです。

0グッド

0クリップ

投稿2016/11/27 01:48

編集2016/11/27 03:01

Javaの正規表現とMatcherクラスを組み合わせた使い方が理解できず、教えていただけないでしょうか?

・やりたいこと
以下のようなhtml文のうち

2016年11月22日
370
370
のみを抜き出したい

<td>2016年11月22日</td><td>370</td><td>370</td><td>2016年11月21日</td><td>1000</td><td>1000</td>

----------コード-----------------------
String str = "<td>2016年11月22日</td><td>370</td><td>370</td><td>2016年11月21日</td><td>1000</td><td>1000</td>";

String regex ="([0-9]{4}年[0-9]{1,2}月[0-9]{1,2}日)(.?)([0-9|,]+)(.?)([0-9|,]+)";
Pattern p2 = Pattern.compile(regex);
Matcher m2 = p2.matcher(str);

while(m2.find()){ day= m2.group(1); num1= m2.group(3); num2= m2.group(5);

・結果
なぜかhtmlの後ろ側に位置する以下の方が取得されてしまう
2016年11月21日
1000
1000

どこに問題があるのかどうか教えていただけないでしょうか、よろしくお願いいたします。

追記
環境はMacOS 10.12.1, Java8, Eclipse4.6.0です。
例えば(.?)のうち最後の部分を(.)に変えると、
String regex ="([0-9]{4}年[0-9]{1,2}月[0-9]{1,2}日)(.?)([0-9|,]+)(.)([0-9|,]+)";

そしてnum2= m2.group(5)を(4)に変えると
while(m2.find()){
day= m2.group(1);
num1= m2.group(3);
num2= m2.group(4);

今度は結果が
2016年11月22日
370

</td><td>370</td><td>2016年11月21日</td><td>1000</td><td>1000</td>

となります。最後の370さえ取得できればよいのですが、この挙動が理解できず。。
わかりずらい表現で申しわけありません。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

swordone

2016/11/27 02:27

私の環境(Windows7、Java8、Eclipse4.5.2)では前の方も後ろの方も取得できましたが、あなたの場合は「後ろだけ」取得されてしまうということですか?
guest

回答2

0

Java

1 String day, num1, num2; 2 3 while(m2.find()) { 4 day = m2.group(1); 5 num1 = m2.group(3); 6 num2 = m2.group(5); 7 8 System.out.println(day + ":" + num1 + ":" + num2); 9 }

2016年11月22日:370:370
2016年11月21日:1000:1000

とちゃんと取れていますが、取れたday, num1, num2を保存していないので、上書きされて後ろの方だけが残る、ということでしょうか?

投稿2016/11/27 02:43

naomi3

総合スコア1105

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

swordone

2016/11/27 03:15

変数宣言されてなくてwhileで変数宣言してみて「これ意味あるのか?」と直接出力したせいで気づかんかった…
guest

0

ベストアンサー

以下のコードで、最初に取得した分
2016年11月22日
370
370
がwhile文を抜けた時三つのStringに入っています
何故以前のコードでは最後の分が変数に入っていたかというと、恐らくはこういうことです
whileを回転させてfind()するたびに三つの変数に正規表現に合致する見つかった部分を代入して行くと、
回転が最後まで行われ、find()がtrueにならなくなってwhile文から抜けた時、最後に見つかった部分が三つの変数に代入された状態になっているからです
以下のコードでは最初に正規表現に合致する部分を見つけて変数に三つの値を代入した直後にbreakでwhileから抜け出しそれを抑止しています

java

1import java.util.regex.Pattern; 2import java.util.regex.Matcher; 3class DAW{ 4 5public static void main(String[] args){ 6 7String str = "<td>2016年11月22日</td><td>370</td><td>370</td><td>2016年11月21日</td><td>1000</td><td>1000</td>"; 8 9String regex ="([0-9]{4}年[0-9]{1,2}月[0-9]{1,2}日)(.*?)([0-9|,]+)(.*?)([0-9|,]+)"; 10Pattern p2 = Pattern.compile(regex); 11Matcher m2 = p2.matcher(str); 12String day=null; 13String num1=null; 14String num2=null; 15 16while(m2.find()){ 17 day= m2.group(1); 18 num1= m2.group(3); 19 num2= m2.group(5); 20break; 21} 22System.out.println(day+":"+num1+":"+num2); 23 24} 25}

投稿2016/11/27 02:56

編集2016/11/27 03:25
退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

an6

2016/11/27 04:46

ありがとうございます、教えていただいた通りに実行したら成功しました。 合わせて正規表現とMatcherクラスを組み合わせた時の仕組みも理解することができました。 今後とも宜しくお願いします。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問