У меня есть такой код:
var r = /(?:^\s*([^\s]*)\s*)(?:,\s*([^\s]*)\s*){0,}$/
var s = " a , b , c "
var m = s.match(r)
m => [" a , b , c ", "a", "c"]
Похоже, что вся строка была сопоставлена, но куда "b"
делась? Я бы предпочел получить:
[" a , b , c ", "a", "b", "c"]
так что я могу сделать m.shift()
с результатом, s.split(',')
но также с удаленными пробелами.
Есть ли у меня ошибка в регулярном выражении или я неправильно понял String.prototype.match
?
javascript
regex
меандре
источник
источник
{0,}
это то же самое, что и*
.s
может также быть' a, c'
или'a,b,c d e, f'
Ответы:
Вот довольно простой и понятный способ сделать это без сложных регулярных выражений.
var str = " a , b , c " var arr = str.split(",").map(function(item) { return item.trim(); }); //arr = ["a", "b", "c"]
Нативный
.map
поддерживается в IE9 и выше: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/mapИли в ES6 + он становится еще короче:
var arr = str.split(",").map(item => item.trim());
И для завершения, вот он в Typescript с информацией для ввода
var arr: string[] = str.split(",").map((item: string) => item.trim());
источник
var arr = str.split(",").map(item=>item.trim());
Вы можете попробовать это без сложных регулярных выражений.
var arr = " a , b , c ".trim().split(/\s*,\s*/); console.log(arr);
источник
Краткий ответ: используйте
m = s.match(/[^ ,]/g);
Ваш RE не работает должным образом, потому что последняя группа соответствует самому последнему совпадению (=
c
). Если вы опустите{1,}$
, будет возвращено совпадение" a , b ", "a", "b"
. Короче говоря, ваш RegExp возвращает столько совпадений, сколько указанные группы, если вы не используетеglobal
флаг/g
. В этом случае возвращаемый список содержит ссылки на все совпавшие подстроки.Для достижения эффекта используйте:
m = s.replace(/\s*(,|^|$)\s*/g, "$1");
Эта замена заменяет каждую запятую (
,
), начало (^
) и конец ($
), окруженные пробелом, на исходный символ (comma
или ничего).Если вы хотите получить массив, используйте:
m = s.replace(/^\s+|\s+$/g,"").split(/\s*,\s*/);
Этот RE обрезает строку (удаляет все пробелы в начале и в конце, затем разбивает строку на
<any whitespace>,<any whitespace>
. Обратите внимание, что символы пробела также включают символы новой строки и табуляции. Если вы хотите придерживаться только пробелов, используйте пробел () вместо
\s
.источник
split
метода.s.match(/[^ ,]+/g)
. Как упоминалось в начале моего ответа,/g
это глобальный флаг, который возвращает все подходящие подстроки.a
,b
иc
, вам нужны три пары скобок (не включая(?:...)
):/(?:^\s*([^\s]*)\s*)(?:,\s*([^\s]*)\s*)(?:,\s*([^\s]*)\s*)$/
Сокращение ES6:
str.split(',').map(item=>item.trim())
источник
Вы можете сделать это для своей цели
EDIT : удаление второй замены, как это предлагается в комментариях.
s.replace(/^\s*|\s*$/g,'').split(/\s*,\s*/)
Сначала
replace
обрезается строка, а затемsplit
функция разбивается'\s*,\s*'
. Это дает вывод["a", "b", "c"]
на входе" a , b , c "
Что касается того, почему ваше регулярное выражение не захватывает 'b', вы повторяете захваченную группу, поэтому захватывается только последнее вхождение. Подробнее об этом здесь http://www.regular-expressions.info/captureall.html.
источник
Итак, наконец, я выбрал
/(?=\S)[^,]+?(?=\s*(,|$))/g
, что дает именно то, что мне нужно: все предложения, разделенные на ',' без окружающих пробелов.' a, OMG abc b a b, d o WTF foo '. match( /(?=\S)[^,]+?(?=\s*(,|$))/g ) => ["a", "OMG abc b a b", "d o WTF foo"]
огромное спасибо!
источник
(?=\S)
- начинайте захват только тогда, когда впереди нет пробелов[^,]+
- фиксируйте как можно больше «не запятых»?
- но не фиксируйте то, что может быть захвачено следующей группой(?=\s*(,|$))
- фиксируйте все пробелы перед запятая или конец строки/g
- повторить всю строкуЕсли вы хотите продолжать использовать регулярное выражение, сохраняйте код простым и без использования ES6:
s.replace(/ /g, '').split(",")
1 - Заменить все пробелы (/ / g) пустыми строками ('')
2 - Затем разделите его на массив
И вуаля
источник