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

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

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

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

正規表現

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

Q&A

解決済

4回答

1635閲覧

正規表現を理解したい

k499778

総合スコア599

Java

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

正規表現

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

0グッド

0クリップ

投稿2017/05/15 12:04

現在Javaで正規表現の勉強をしています。

結論から言うと、
以下のコードがなぜ8になるか理解したいです。

java

1class Test { 2 public static void main(String[] args) { 3 String data = "This is a pen."; 4 String[] ary = data.split("\\S"); 5 System.out.print(ary.length); 6 } 7} 8

正規表現「\S」が非空白文字を示しているというのは知っています。
(私の環境はmacなので「\S」で想定の結果になりましたが、Windowsだと「¥¥S」と書いたほうがいいかもしれません。)

ただ非空白文字が調べましたがよく理解できず、対象の文字列をどこで分けるか、どのように分けるかが理解できていません。

もし分かる方がいれば教えていただけると助かります。

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

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

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

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

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

guest

回答4

0

自己解決

toutouさんのリンク先にある説明が一番しっくりきたので備忘録の為まとめます。

非空白文字と言われるとなじみがないためわかりづらい。
そこで非空白文字を全部カンマに、空文字をアンダースコアに置き換える。

java

1class Test { 2 public static void main(String[] args) { 3 String data = "This is a pen."; 4 String data1 = ",,,,_,,_,_,,,,"; 5 6 String[] ary1 = data1.split(","); // 第二引数なしは「末尾の空文字をカット」 7 System.out.println(ary1.length); // 8 -① 8 String[] ary2 = data1.split(",", -1); // 第二引数−1は「制限なし」 9 System.out.println(ary2.length); // 12 -② 10 } 11}

data1をカンマで区切ると以下のようになる。

(1)空文字
(2)空文字
(3)空文字
(4)空文字
(5)_
(6)空文字
(7)_
(8)_
(9)空文字
(10)空文字
(11)空文字
(12)空文字

12個に区切られる。(②の場合)

しかしsplitメソッドの第二引数がなしの場合は、末尾の空文字がカットされるため
(9)~(12)を数えず、
8個となる。(①の場合)

つまり今回の問題の回答は8となる。

投稿2017/05/15 14:28

k499778

総合スコア599

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

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

0

まず、どこで分かれるかについては次のようなメソッド呼び出しの結果をみればわかりやすいと思います。

"This is a ".replaceAll("\\S", "|");

さて、なぜ8かは正規表現云々の話とはほとんど関係なくてsplitの仕様です。

"This is a " ...(1)
"This is a pen." ...(2)

上記のどちらもsplitの結果は同一となります。(1)の結果が8になるのは疑問ではないと思います。(2)が8になるから疑問を持たれたのでしょう。こうなる理由はsplitのリファレンスをお読みになれば明らかになるはずです。

(私の環境はmacなので「\S」で想定の結果になりましたが、Windowsだと「¥¥S」と書いたほうがいいかもしれません。)

おっしゃりたいことがわかりませんでした。本件についていえばWindows, Mac, LinuxいずれのOSで実行しても結果は同じです。

投稿2017/05/15 12:38

KSwordOfHaste

総合スコア18394

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

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

k499778

2017/05/15 12:44

回答ありがとうございます。 splitをもう少し勉強してみます。 よく正規表現は¥¥Sという書き方をしていたので、Macならではの書き方なのかと思ってしまいました。 そうだったんですね。勉強になりました。
KSwordOfHaste

2017/05/15 13:00

> 勉強 リファレンスさえ読めば、それが書いてある・・・と思ったのですが、リファレンスに書かれている表現が硬すぎてわかりにくいということだったでしょうかね。だとすると慣れるしかないですが。表現は堅いので読みやすいとは言えないかも知れませんが、一番確実に明確に仕様が書いてあるのはリファレンスであることが多いですので。 > Macならではの書き方 OSに依存する仕様は例えば「パスセパレーター」のようにJava側で決められず、各OSでの決まりごとに左右されるものです。正規表現の仕様についてはOSではなく、「どの正規表現ライブラリーを使うか」によって変わります。つまりJavaなのかjavascriptなのかといったような違いです。
k499778

2017/05/15 13:44

そうですね。毎回リファレンスは見るのですがやはり腰を据えて読まないと本質的なところがなかなか理解しづらい印象です。ある程度Javaの経験も増えてきて、本当に詳しく書いてあるのはリファレンスであり、それが神様だということを実感してきたのでそろそろ慣れていこうとは思っています。 パスセパレーター...そのような言葉があるのですね。まだなかなか馴染みのないところで踏み込んでいない分野ですね。新しいことが知れてまた丁寧に教えてくださる回答者様がいて良かったです。感謝しています。
guest

0

Javaの正規表現について - Java [解決済 - 2015/09/13] | 教えて!goo
同じ人?って思っちゃうくらい同じ質問がありましたね。

投稿2017/05/15 12:26

toutou

総合スコア2050

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

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

k499778

2017/05/15 12:38

回答ありがとうございます。 同一人物ではないですが、笑 ほとんど同じ内容ですね。 ちなみにどのように検索されたか教えたもらうことはできますか? そこが私の課題だと思ったので
toutou

2017/05/15 12:46

残念ながら自分はあまり正規表現に詳しくないので、\\sって何だっけなと思い「java 正規表現 非空白文字」でとりあえずぐぐってみたら見つかりましたね。これから解析する予定でした。
k499778

2017/05/15 13:39

返答ありがとうございます。参考にさせていただきます。
guest

0

JAVAが分かっていないので、理解が間違っているのかもしれませんが、8という解がわからなかったため、JavaScript で試してみました。

JavaScript

1data = "This is a pen."; 2ary = data.split(/\S/); 3m = data.match(/\S/g); 4console.log(ary);//["", "", "", "", " ", "", " ", " ", "", "", "", ""] 5console.log(m);//["T", "h", "i", "s", "i", "s", "a", "p", "e", "n", "."] 6console.log(ary.length);//12

こちらは、想定通り(?)12になります。
できれば、この確認したコードのように、ary の中身と、合致文字列を追記していただけないでしょうか?

投稿2017/05/15 12:43

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

honami

2017/05/15 13:08 編集

JavaScriptとJavaではsplit()のlimit引数における空文字の扱い方が異なりますので同様にはならないです。 これは言語の仕様であり、リファレンスに書かれてあること、かつ質問者の方にそれを探す意欲があるのであえて書くことはしませんが、興味があれば「split limit 空文字」なんかで探すことで理解できると思います。
退会済みユーザー

退会済みユーザー

2017/05/15 13:15 編集

KSwordOfHaste さんの回答見て、仕様が違うらしいと気がつきました^^; ご指摘ありがとうございます。 他の言語でも同じような現象が発生するようなので、良い勉強になりました。
k499778

2017/05/15 14:33

te2jiさん回答ありがとうございます。 自分用の備忘録にもまとめましたが、 今回の質問のコードのary変数の中身は以下になります。 (0)空文字 (1)空文字 (2)空文字 (3)空文字 (4)_ (5)空文字 (6)_ (7)_
退会済みユーザー

退会済みユーザー

2017/05/15 14:41

いや、リファレンス読んだから仕様の違いは分かったよ。 なんで他の説明を重要視するのか理解できないです。。。
k499778

2017/05/15 15:35

そんな言い方しなくてもいいじゃないですか笑 一応若輩者ながら調べて答えようと思ったのに。。 ん?
退会済みユーザー

退会済みユーザー

2017/05/15 21:04

普通の感覚だと思いますよ。 仕様のことを確認するのに、公式の文書以外を参考にするとろくなことにならない。 他の人のコメントにも、リファレンス読めって書いてあるの見えてます? 今回の質問に対して、私が行ったのは以下のとおりです。 1,実際の挙動を確認しようとした 2,実際の挙動が確認できなかったが仕様が違うと指摘をいただいた 3,公式文書で仕様を確認 4,公式文書内の > Trailing empty strings are therefore not included in the resulting array. で理解する。 追加で > public String[] split(String regex, int limit) の説明をみて、たしかに「書かれている表現が硬すぎてわかりにくいということだったでしょうかね。」というコメントも理解する。 ただ、public String[] split(String regex) に関しては、挙動の違いが明確に書いてあるので、仕様確認はそこで完了です。 仕様確認において、リファレンスで挙動を確認するのは、エンジニアが身につけるべき常識です。ちゃんと調べ方を身に着けないと、使い物にならないです。
k499778

2017/05/15 21:53 編集

それはわかっています。 リファレンスの重要性やそれに慣れていくことは大事だと思いますし、回答者様の具体的な操作はご参考になります。 ただ聞いておいてそのような上から言う言い方をする感覚が気になりました。 ご指摘をいただいたとあったので、ご理解されたのかなと思いつつも回答者様が「ary の中身と、合致文字列を追記していただけないでしょうか?」とおっしゃったのでまだ情報として書いていない具体的な配列の中身を実際に動かして調べて追記した。そしたら思わぬ角度からの返答が来た。 そしてリファレンス読みましたよ。 splitの仕様を見たからsplitの第二引数によるsplitの仕様の違いを理解しましたし、 自己回答(自分の備忘録)にもまとめました。もちろんレベルは私が再度この投稿を見直した時わかりやすいように自分に合わせているので、回答者様には物足りないかもしれませんが。そこはいいと思います。私の質問なので。 おっしゃっている部分の「末尾の空文字をカットする」という点も自己回答に踏まえたつもりです。
退会済みユーザー

退会済みユーザー

2017/05/15 22:18

> ただ聞いておいてそのような上から言う言い方をする感覚が気になりました。 猛烈なブーメランなのですが^^; あなたがリファレンスを読むことを期待して、回答者がリファレンスを読むように誘導してくれているにもかかわらず、そうでは無いページを最重要視するって、相当ひどい行為なの理解してますか? > そしたら思わぬ角度からの返答が来た。 > そしてリファレンス読みましたよ。 良かったです。このコメントしたかいがありました。
k499778

2017/05/15 23:40

違うんですよ。回答者様に返答する前に自己回答載っけていてリファレンス読んだ上での内容載っけていたのにすごく強く来れたので、え?ってなったんですよ笑 リファレンスの重要性は伝わりました。ありがとうございました。
退会済みユーザー

退会済みユーザー

2017/05/16 00:07

KSwordOfHaste さんと honami さんに対しての申し訳ない思いは共有できないようなので、コメントはここまでにしますが、もう少し回答者を理解した方がいいですよ。。。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問