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

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

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

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

解決済

2回答

2062閲覧

タグ文字列を個別に配列に格納

tkshp

総合スコア174

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

1クリップ

投稿2020/04/16 17:05

前提・実現したいこと

以前、こちらで質問した内容と関連があるのですが、
タグ文字列を個別に配列に格納するにはどうすればよいでしょうか?

JavaScript

1var str = "<div>要素1</div><div>要素2</div><div>要素3</div>";

を、

JavaScript

1arr = ["<div>要素1</div>", "<div>要素2</div>", "<div>要素3</div>"]

のように格納するイメージです。

試したこと

以前の質問では、

JavaScript

1<div>要素1</div><div>要素2</div><div>要素3</div>

のDOMを作成してから、

querySelectorAll("div")

メソッドを呼び出せば、配列に格納できるでは?と考えていたのですが、
そもそも上記はDOMでないことをご教示いただいたので、
今回、意図したいことにどういう方法で実装できるか教えていただきたいです。
ご教示お願いします。

補足情報(FW/ツールのバージョンなど)

JavaScript

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

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

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

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

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

hoshi-takanori

2020/04/16 20:32

最終的に何をしたいのか分かりません。要素1、要素2、要素3はどのような内容ですか? また、配列に格納した後はどのように利用する予定ですか?
tkshp

2020/04/19 12:44

配列に格納した後は、要素が重複するものを削除するという目的でした。配列格納後の処理は実装できていました。質問のようなHTML文字列を配列に格納するにはどうすればいいか知りたくなり、質問させていただきました。
guest

回答2

0

ベストアンサー

こんにちは。以下のようにしてみると、いかがでしょうか?

javascript

1var str = "<div>要素1</div><div>要素2</div><div>要素3</div>"; 2 3var parser = new DOMParser(); 4var doc = parser.parseFromString(str, "text/html"); 5var divs = doc.querySelectorAll("div"); 6var divStrings = [...divs].map(e => e.outerHTML); 7 8console.log(divStrings); // => ["<div>要素1</div>", "<div>要素2</div>", "<div>要素3</div>"]

 

もしくは、正規表現を使ってもできます。

javascript

1var str = "<div>要素1</div><div>要素2</div><div>要素3</div>"; 2 3var divs = str.split(/(?<=</div>)\s*/); 4 5console.log(divs); // => ["<div>要素1</div>", "<div>要素2</div>", "<div>要素3</div>"]

追記

コメントから頂きました質問に回答します。

質問 1

・質問1。
親要素にdivがなく、divが3個並列に並んでいるものは、DOMではないと思っていたのですが、
parseできているので、divが3個並列に並んでいるものもDOMになるということでしょうか?

「divが3個並列に並んでいるものもDOMになる」
という解釈よりは、
「divが3個並列に並んでいる文字列でもDOMParserはparseしてくれて、(ドキュメントノードをルートとする、) DOMツリーを構築してくれる。」
という解釈のほうがより正確です。

ついては、

javascript

1var str = "<div>要素1</div><div>要素2</div><div>要素3</div>"; 2 3var parser = new DOMParser(); 4var doc = parser.parseFromString(str, "text/html");

というコードによって、変数 doc が参照するノードをルートとするDOMツリーがどのようなものになっているのかを表す資料を作成しました。(一枚ものです。スライドのタイトル Figure of DOM tree for the Q#254207 of teratail をクリックするとspeakerdeckのサイトにいき、拡大表示されます。)

md(!f3237ab600954ae49d6a328f73f6acbc,1.41436464088398)


上記の絵をコードで確認するには、doc から firstChildnextSibling で、ノードをたどっていき、各ノードの、nodeType, tagName, nodeValue といったプロパティの値を確認するとよいかもしれません。

質問 2

・質問2。
[...divs]の[...XXX]という記法はどういった処理ですか?

...スプレッド構文です。divs は querySelectorAll の返したNodeListオブジェクトが入っています。NodeListオブジェクトは配列(Array)ではありませんが、イテラブル(iterable)なオブジェクトです。イテラブルなオブジェクトに対して、 ... を使うと、最初から最後までのイテレーションによって発生(yield)された値のシーケンスが得られます。これを[] でくくって [...divs] とすると、divsの要素を要素とする配列(Array)が得られます。イテラブルとは何か?ということになると、イテレーターについて知る必要があります。以下はMDNの該当ページです。

質問 3

・質問3。

 正規表現がわからなく調べたのですが、
は直前の文字の0回以上の繰り返しなので、\sは、0回以上の空白(0回の場合は、空文字)で、
つまり、splitで</div>の後の、0回以上の空白で区切っているかと思うのですが、空白を考慮しているのは、

<div>要素1</div><div>要素2</div> だけでなく、 <div>要素1</div> <div>要素2</div> という文字列にも対応させるためなのかと考えたのですが、 では、単なる空文字は*で表現できるのかなと思い、 /(?<=</div>)*/ と試したところ、正規表現エラーとなりました。 <div>要素1</div><div>要素2</div>の場合の</div>の後の空文字は正規表現でどう表現できますか? \s*だと空文字と同時にスペースも含まれますが、これしか表現方法はないですか?

はい。おっしゃるとおり、 \s* はちょっと気を利かせ過ぎました。

入力される文字列が、"<div>要素1</div><div>要素2</div><div>要素3</div>" というような、</div>から次の <div> までの間に空白文字がない前提であれば \s*は不要で、以下

javascript

1var divs = str.split(/(?<=</div>)/);

で、意図した結果になります。

投稿2020/04/16 18:37

編集2020/04/18 08:02
jun68ykt

総合スコア9058

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

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

tkshp

2020/04/17 08:15

ご回答ありがとうございます。 すみません、3点質問があります。 ・質問1。  親要素にdivがなく、divが3個並列に並んでいるものは、DOMではないと思っていたのですが、  parseできているので、divが3個並列に並んでいるものもDOMになるということでしょうか?   ・質問2。  [...divs]の[...XXX]という記法はどういった処理ですか? ・質問3。  正規表現がわからなく調べたのですが、  *は直前の文字の0回以上の繰り返しなので、\s*は、0回以上の空白(0回の場合は、空文字)で、 つまり、splitで</div>の後の、0回以上の空白で区切っているかと思うのですが、空白を考慮しているのは、 <div>要素1</div><div>要素2</div> だけでなく、 <div>要素1</div> <div>要素2</div> という文字列にも対応させるためなのかと考えたのですが、 では、単なる空文字は*で表現できるのかなと思い、 /(?<=</div>)*/ と試したところ、正規表現エラーとなりました。 <div>要素1</div><div>要素2</div>の場合の</div>の後の空文字は正規表現でどう表現できますか? \s*だと空文字と同時にスペースも含まれますが、これしか表現方法はないですか?
jun68ykt

2020/04/18 01:37

コメントありがとうございます。 3点のご質問に対する回答を追記しましたので、ご確認ください。参考になれば幸いです。
tkshp

2020/04/19 12:41

ご回答ありがとうございます。 知らなかった点が多々ありましたが、じっくり読ませていただき、とても勉強になりました。 質問1に関しては、 console.log(doc); console.log(doc.firstChild.firstChild); 等で確認しました。 質問2に関してもスプレッド構文でサンプルコードを作り、試してみました。 質問3に関しては、なるほど、空文字の表現は何も書かないことで指定できるのですね。こちらも試して確認しました。 たくさんのことをご丁寧にご教示いただき、とても勉強になりました。 大変ありがとうございました。
jun68ykt

2020/04/19 15:14

どういたしまして。 ご丁寧な返信、ありがとうございます。 参考になりましたようで、よかったです。
guest

0

javascript

1var str = "<div>要素1</div><div>要素2</div><div>要素3</div>"; 2var dummy=Object.assign(document.createElement('body'),{innerHTML:str}); 3console.log([...dummy.querySelectorAll('*')].map(x=>x.outerHTML));

投稿2020/04/17 00:09

編集2020/04/17 00:11
yambejp

総合スコア116734

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

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

tkshp

2020/04/19 12:42

ご回答ありがとうございます。 DOMの作成方法をご教示いただき、ありがとうございます。 とても勉強になりました。ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問