как разбить строку по двойным кавычкам, избегая экранированных кавычек - PullRequest
0 голосов
/ 02 марта 2020

Как разбить приведенную ниже строку

var test = 'sample "test""test2"   "test3\\"" sample2"last';

на массив ['sample','"test"','"test2"','"test3\\""','sample2"last'], используя javascript regx?

Некоторые примеры ввода и ожидаемые результаты добавляются ниже.

sample1 : ' test1 "test2" test3 "test four\\"" test" d'
output [' test1','"test2"','test3','"test four\\""','test" d']

sample2 : ' test1 test2'
output [' test1 test2']

sample3 : ' test1 "sub test2'
output [' test1 "sub test2']

sample4 : ' test1 "sub test2"'
output [' test1 ','"sub test2"']

sample5 : ' "test1" "sub test2" here'
output ['"test1"','"sub test2"', 'here']

Ответы [ 5 ]

2 голосов
/ 02 марта 2020

Вы можете разделить строку не символами алфавита c, а затем удалить любой элемент длиной 0.

var test = 'sample "test""test2"   "test3\"" sample2"';

var array = test.split(/\W/g).filter(e => e.length>0);

console.log(array);
1 голос
/ 02 марта 2020

Это регулярное выражение должно работать для вас для разделения:

/\s*"[^"\\]*(?:\\.[^"\\]*)*"\s*|.+?(?="[^"\\]*(?:\\.[^"\\]*)*"|$)/g

Код:

var input = [` test1 "test2" test3 "test four\\"" test" d`, ` test1 test2`, ` test1 "sub test2`, `' test1 "sub test2"`, ` "test1" "sub test2" here`];

const re = /\s*"[^"\\]*(?:\\.[^"\\]*)*"\s*|.+?(?="[^"\\]*(?:\\.[^"\\]*)*"|$)/g;

input.forEach(el => {
  console.log('<<', el, '>>');
  var arr = el.match(re);
  arr.forEach(i => console.log(i));
});

Подробности RegEx:

  • "[^"\\]*(?:\\.[^"\\]*)*": сопоставить строку в кавычках, игнорируя экранированные кавычки
  • |: ИЛИ
  • .+?(?="[^"\\]*(?:\\.[^"\\]*)*"|$): соответствует 1+ любым символам, за которыми должна следовать строка в кавычках или конец строки.
0 голосов
/ 02 марта 2020

Чистое решение регулярного выражения: / +|(?<!\\")(?<=")(?=")/

Это соответствует либо пробелу (ам), либо пустым строкам, которые

  • предшествуют ", но не \"
  • с последующим "

var test = 'sample "test""test2"   "test3\\"" sample2"last';
console.log(test.split(/ +|(?<!\\")(?<=")(?=")/));
0 голосов
/ 02 марта 2020

Если вы можете использовать отрицательный вид сзади, вы можете использовать этот шаблон:

test.split(/(?<!\\)"/).map(i => i.trim()).filter(i => i != '')

Обратите внимание, что отрицательный взгляд назад является недавним дополнением к JS движкам. Его можно использовать с V8, который используется, например, в Chrome.

Если вы не можете использовать отрицательный взгляд сзади, используйте обходной путь: переверните строку, используйте отрицательный взгляд вперед, а затем снова поверните снова:

test
  .split('')
  .reverse()
  .join('')
  .split(/"(?!\\)/)
  .map(i => i.trim())
  .filter(i => i != '')
  .map(i => i.split('').reverse().join(''))
  .reverse()

Используемые шаблоны:

  • "(?!\\) - отрицательный прогноз: совпадение ", за которым не следует \
  • (?<!\\)" - отрицательный lookbehind: match ", которому не предшествует \
0 голосов
/ 02 марта 2020

Немного запутанный, но он выполняет свою работу:

  • сначала замените маскированные кавычки строкой маркера x
  • , затем: сопоставьте с любым " -прикрепленным части строки, используя метод RegExp.exec() несколько раз
  • , захватите первый элемент каждого результата, удалите кавычки и замените строку маркера исходной кавычкой и
  • pu sh в массив результатов

var test = 'sample "test""test2"   "test3\\"" sample2"';
var x='@#@',xr= RegExp(x,'g');
var rx=/"[^"]+"/g; // matches "-enclosed strings
var a,arr=[];
while (a=rx.exec(test.replace(/\\"/g,x)))
arr.push(a[0].replace(/"/g,'').replace(xr,'"'));

console.log(arr);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...