- ベストアンサー
再挑戦:分割子が混在したデータの成型コードは?
- 分割子が混在したデータを統一する成型コードの作成方法を教えてください。
- データにはさまざまな分割子が存在し、それらを1つの分割子に統一する必要があります。
- 成型コードの仕様として、二重引用符、一重引用符、タブ区切り、半角空白、パイプ(縦棒)があります。
- みんなの回答 (5)
- 専門家の回答
質問者が選んだベストアンサー
同じブラウザ環境(Google Chrome バージョン: 113.0.5672.127(Official Build) (64 ビット))で試して見ましたが、再現せずでした。 step0を下記のコードに差し替えてみたらどうなるでしょうか。 // step.0 分割子をパイプに統一し、不要な引用符と行頭行末パイプ除去 var text = data.innerText.replace(/\t+| +|","|','/g, '|').replace(/"|'|^\||\|$/gm, '');
その他の回答 (4)
- fji-jp
- ベストアンサー率84% (11/13)
改めて1つの分割子に統一するコードを作成してみました。 <h1>JS 分割子が混在したデータの成型コードは?</h1> <pre> さまざまな分割子が混在したデータがあります。 これを1つの分割子に統一するには どんなコードでできますか? 【仕様】 [分割子] ・二重引用符 ・一重引用符 ・タブ区切り ・・・ 単語と単語の間 ・半角空白 同上 ・パイプ(縦棒)・・・ 行頭と末尾に有る、無いの2ケース [データ型式] (注) 適合しないデータが含まれています 1列目:3桁カンマ区切り 2列目:文字データ 3列目:整数・小数(負数を含む) [備考] ・空白行は詰める ・エラーデータは「****」と出力 </pre> <pre id="data"> 1,234 あさがお 23.45 7,904 みかん 0.92 5,021 うさぎ 5.63 8,753 えんどう 1.724 2,657 いちご 10.87 9,841 ひまわり 77.33 432 ベニバナ 4.09 7,123 メロン 98.14 432 しらゆり 4.09 6,722 ナツメグ 65.1 "333,333","fish","67.82" "98,765","animal","26.5" "216,017","lion","5.74" "60,580","cat","31.07" "43,604","river","25.94" '90,742','lamp','0.45' '23,809','teacup','7.23' '3,582','dish','80.72' '5,600','stove','59.35' '4,65','soap','23.84' 9,001|violin|28.03 5,345|guitar|4.52 |4,890|goldfish|135.45| |2,8760|mountain|79.43| |5,032|radio|17.03| </pre> <div>分割子:<select id="divType"></select></div> <textarea id="output" cols=60 rows=30></textarea> <script> var divTypes = [ {name:'二重引用符', quot:'"', sep:',', outer:''}, {name:'一重引用符', quot:"'", sep:',', outer:''}, {name:'タブ区切り', quot:'', sep:'\t', outer:''}, {name:'半角空白', quot:'', sep:' ', outer:''}, {name:'パイプ区切り', quot:'', sep:'|', outer:''}, {name:'パイプ行頭行末', quot:'', sep:'|', outer:'|'} ]; function makeOpt(i, v) {let opt=document.createElement("option"); opt.setAttribute("value", i); opt.innerHTML = v; return opt;} divTypes.forEach((v,i)=>{divType.innerHTML = divType.innerHTML + '<option value="' + i + '">' + v.name + '</option>';}); doChoose(); function doChoose() { // step.0 分割子をパイプに統一し、不要な引用符と行頭行末パイプ除去 var text = data.innerText.replace(/\t| |","|','/g, '|').replace(/"|'|^\||\|$/gm, ''); // step.1 データから、分割子を除いた単語として配列に格納 var csv = text.split(/\r\n|\n|\r/).filter(s=>s).map(s=>s.split('|')); // step.2 エラーデータは「****」に変換 csv=csv.map(s=>s.map((v,i)=>(i!=0||v==Number(v.replace(/,/g,'')).toLocaleString())?v:'****')); // step.3 分割子を指定してテキストエリアに出力 var f = divTypes[divType.value]; output.value = csv.map(v=>(f.outer + v.map(v=>(f.quot + v + f.quot)).join(f.sep)) + f.outer).join('\r\n'); }; divType.addEventListener('change', doChoose); </script>
補足
お力添えを頂きまして感謝申し上げます。 下記のブラウザにて確認してみました。 Google Chrome バージョン: 113.0.5672.127(Official Build) (64 ビット) 検証結果は下記のとおりになりました。(元データは3列) ■二重引用符・・・一部に5列あり "1,234","","あさがお","","23.45" "7,904","","みかん","","0.92" "5,021","","うさぎ","","5.63" "8,753","","えんどう","","1.724" "2,657","","いちご","","10.87" ■一重引用符・・・一部に5列あり '1,234','','あさがお','','23.45' '7,904','','みかん','','0.92' '5,021','','うさぎ','','5.63' '8,753','','えんどう','','1.724' '2,657','','いちご','','10.87' ■タブ区切り・・・一部に5列あり(#に置換して確認) 7,904##みかん##0.92 5,021##うさぎ##5.63 8,753##えんどう##1.724 2,657##いちご##10.87 ■半角空白・・・一部に5列あり(#に置換して確認) 7,904##みかん##0.92 5,021##うさぎ##5.63 8,753##えんどう##1.724 2,657##いちご##10.87 ■パイプ区切り・・・一部に5列あり 1,234||あさがお||23.45 7,904||みかん||0.92 5,021||うさぎ||5.63 8,753||えんどう||1.724 2,657||いちご||10.87 ■パイプ行頭行末・・・一部に5列あり |1,234||あさがお||23.45| |7,904||みかん||0.92| |5,021||うさぎ||5.63| |8,753||えんどう||1.724| |2,657||いちご||10.87| もう少し作り込めば完成できそうです!
- fji-jp
- ベストアンサー率84% (11/13)
こちらでの検証結果では、前回提示した引用符を残したコードでは、添付ファイルの通り問題点は発生せずに正常動作しています。 そのため、検証いただいた結果が再現しないため、これ以上の手直しおよび力添えは、不可となります。 問題点に挙げられた元データに3桁区切り記号が含んでいても、半角空白が正常出力で、タブ区切りが5列になる箇所がある点については、最初に「\t」を「|,」に置換すると再現はしましたが、提示したコードではありません。
補足
お力添えをいただき、感謝申し上げます。 添付写真のものは No.2 コードでの出力結果ですよね? この場合、 ・1~6行目はカンマ区切りで 4列になっている ・二重引用符と一重引用符が一部のみで、 全体が統一されていない 以上の点が惜しいです。 「1つの分割子に統一する」というテーマ それが問題です。
- fji-jp
- ベストアンサー率84% (11/13)
引用符を残した下記コードでどうでしょうか。 <script> //例 button1.onclick = function(){ // step.0 分割子をパイプに統一し、行頭行末パイプを除去 var text = data.innerText.replace(/\t| /g, '|').replace(/","/g, '"|"').replace(/','/g, "'|'").replace(/^\||\|$/gm, ''); // step.1 データから、分割子を除いた単語として配列に格納 var csv = text.split(/\r\n|\n|\r/).filter(s=>s).map(s=>s.split('|')); // step.2 エラーデータは「****」に変換 csv=csv.map(s=>s.map((v,i)=>(i!=0||v.replace(/"|'/g,'')==Number(v.replace(/,|"|'/g,'')).toLocaleString())?v:'****')); // step.3 分割子を指定してテキストエリアに出力 output.innerHTML = csv.map(i=>i.join(',')).join('\r\n'); }; </script>
補足
ご回答ありがとうございます。 >引用符を残した下記コードでどうでしょうか。 下記は検証結果です。 fji-jpさんのコードによる出力結果 1,234,,あさがお,,23.45 7,904,,みかん,,0.92 5,021,,うさぎ,,5.63 8,753,,えんどう,,1.724 2,657,,いちご,,10.87 9,841,ひまわり,77.33 432,ベニバナ,4.09 7,123,メロン,98.14 432,しらゆり,4.09 6,722,ナツメグ,65.1 "333,333","fish","67.82" "98,765","animal","26.5" "216,017","lion","5.74" "60,580","cat","31.07" "43,604","river","25.94" '90,742','lamp','0.45' '23,809','teacup','7.23' '3,582','dish','80.72' '5,600','stove','59.35' ****,'soap','23.84' 9,001,violin,28.03 5,345,guitar,4.52 4,890,goldfish,135.45 ****,mountain,79.43 5,032,radio,17.03 [修正箇所] ・出力先はテキストエリアなので × output.innerHTML = csv.map(i=>i.join(',')).join('\r\n'); ○ output.value = csv.map(i=>i.join(',')).join('\r\n'); [問題点] ・列数と引用符について >3列のデータのはずが、5列になる箇所がある >引用符が付いていないデータがある (例)1,234,,あさがお,,23.45 ・元データに3桁区切り記号を含んでいるため、 分割子にカンマのみは不適合 もう少し手直しが必要のようです。 よろしくお願いいたします。
- fji-jp
- ベストアンサー率84% (11/13)
下記のコードでどうでしょうか <script> //例 button1.onclick = function(){ // step.0 分割子をパイプに統一し、不要な引用符と行頭行末パイプ除去 var text = data.innerText.replace(/\t| |","|','/g, '|').replace(/"|'|^\||\|$/gm, ''); // step.1 データから、分割子を除いた単語として配列に格納 var csv = text.split(/\r\n|\n|\r/).filter(s=>s).map(s=>s.split('|')); // step.2 エラーデータは「****」に変換 csv=csv.map(s=>s.map((v,i)=>(i!=0||v==Number(v.replace(/,/g,'')).toLocaleString())?v:'****')); // step.3 分割子を指定してテキストエリアに出力 output.innerHTML = csv.map(i=>i.join(',')).join('\r\n'); }; </script>
補足
説明不足で申し訳ございません。 ・二重引用符 ”AAA”,”BBB”,”CCC” ・一重引用符 'DDD','EEE','FFF' 上記は引用符で囲んでカンマ区切りになります。
お礼
完璧な結果出力でした。 非の打ちどころがないコードで、 とても良い勉強になりました。 どうもありがとうございました。 m(_ _)m
補足
確認した結果、どの場合も正常に動作しました。