JavaScript 作 ▸ 2019-04-15 13:17 JavaScript 文字列をスペースでsplit、ただしダブルクォートの内側は残す #JavaScript 正規表現わかんないから普通にやった 。 ゚(゚^ω^゚)゚。 /** * 文字列を半角スペースで区切る。ダブルクォートの内側は区切らない (エスケープされていれば区切る)。 * @param {String} str 文字列 * @return {Array} 区切られた文字列の配列 */ function splitNicely(str) { if (str !== String(str)) { return [str]; } const arr = []; let buff = ''; let escaped = false; let quoted = false; for (let i = 0, len = str.length; i < len; ++i) { const c = str.charAt(i); if (c === '\\') { escaped = true; } else { if (!escaped && c === '"') { const prev = str.charAt(i - 1); const next = str.charAt(i + 1); if (!quoted && (prev === '' || prev === ' ')) { quoted = true; } else if (quoted && (next === '' || next === ' ')) { quoted = false; } else { buff += c; } } else if (!quoted && c === ' ') { arr.push(buff); buff = ''; } else { buff += c; } escaped = false; } } arr.push(buff); return arr; } // こんな感じ console.log( splitNicely(`aaa "bbb" ccc`) ); // -> ["aaa", "bbb", "ccc"] console.log( splitNicely(`a"aa b"bb c"c"c`) ); // -> ["a"aa", "b"bb", "c"c"c"]通ったテストfunction assert(actArr, expArr) { console.log('act=', actArr, 'exp=', expArr); const len = actArr.length; if (len !== expArr.length) { throw new Error(actArr.length +' !== '+ expArr.length); // 要素数違ったらNG } for (let i = 0; i < len; ++i) { if (actArr[i] !== expArr[i]) { throw new Error(actArr[i] +' !== '+ expArr[i]); // 中身違ったらNG } } } assert( splitNicely(), [undefined] ); assert( splitNicely(null), [null] ); assert( splitNicely(``), [''] ); assert( splitNicely(`aaa`), ['aaa']); assert( splitNicely(`aaa bbb ccc`), ['aaa', 'bbb', 'ccc'] ); assert( splitNicely(`aaa "bbb" ccc`), ['aaa', 'bbb', 'ccc'] ); assert( splitNicely(`a"aa b"bb c"c"c`), ['a"aa', 'b"bb', 'c"c"c'] ); assert( splitNicely(`"" aaa bbb ccc`), ['', 'aaa', 'bbb', 'ccc'] ); assert( splitNicely(`"aaa bbb" ccc`), ['aaa bbb', 'ccc'] ); assert( splitNicely(`aaa "bbb ccc"`), ['aaa', 'bbb ccc'] ); assert( splitNicely(`aaa "bbb ccc" ddd`), ['aaa', 'bbb ccc', 'ddd'] ); assert( splitNicely(`"\\"aaa bbb" ccc`), ['"aaa bbb', 'ccc'] ); assert( splitNicely(`"aaa bbb\\"" ccc`), ['aaa bbb"', 'ccc'] ); assert( splitNicely(`"aa\\"a b\\"bb" ccc`), ['aa"a b"bb', 'ccc'] ); assert( splitNicely(`"" "aa\\"a b\\"bb" ccc`), ['', 'aa"a b"bb', 'ccc'] ); assert( splitNicely(`GET 200 "http://aaa/bbb.html" "123 \\"456\\" 789" xxxxxx`), ['GET', '200', 'http://aaa/bbb.html', '123 "456" 789', 'xxxxxx'] );