Как разбить строку по шаблону из одного или нескольких повторяющихся символов и сохранить совпадение?

Например, получите строку abaacaaa, символ a, разделите строку, чтобы получить ['ab', 'aac', 'aaa'].

string = 'abaacaaa'
string.split('a')      // 1. ["", "b", "", "c", "", "", ""]
string.split(/(?=a)/)  // 2. ["ab", "a", "ac", "a", "a", "a"]
string.split(/(?=a+)/) // 3. ["ab", "a", "ac", "a", "a", "a"]

string.split(/*???*/)  // 4. ['ab', 'aac', 'aaa']

Почему выражение 3-й выводит то же значение, что и 2-й, даже если + представлен после a, и что помещать в 4-й?


Редактировать:

string.match(/a+[^a]*/g) не работает должным образом в babaacaaa.

string = 'babaacaaa'     // should be splited to ['b', 'ab', 'aac', 'aaa']
string.match(/a+[^a]*/g) // ["ab", "aac", "aaa"]

В каком контексте вы ожидаете, что строка будет разделена?

Ankit Agarwal 18.10.2018 13:49

Я хочу повернуть струну как можно более лаксикографически. Например, с abaca на aabac

djy 18.10.2018 13:50

Незакрепленные опережающие просмотры проверяют каждую позицию во входной строке. Следовательно, 2 = 3. Кроме того, 'abaacaaa'.match(/a+[^a]*/g), похоже, работает как 4).

Wiktor Stribiżew 18.10.2018 13:51

В python вы также можете использовать поиск назад, чтобы найти позицию, которую вы запрашивали для выполнения операции разделения (например, ^|(?<=[^a])(?=a+(?:[^a]|$)), но, к сожалению, в настоящее время поиск назад не поддерживается javascript. Проверьте: regex101.com/r/qDrobh/2

gaw 18.10.2018 14:12
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
4
84
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

let string = 'abaacaaa'
let result = string.match(/a*([^a]+|a)/g)
console.info(result)

string = 'babaacaaa'
result = string.match(/a*([^a]+|a)/g)
console.info(result)
Ответ принят как подходящий

Решения 2 и 3 равны, потому что незакрепленные опережающие просмотры проверяют каждую позицию во входных данных. нить. (?=a) проверяет начало строки в abaacaaa и находит совпадение, первый пустой результат отбрасывается. Затем он пытается найти a, совпадений нет, поскольку символ справа - это b, механизм регулярных выражений переходит на следующую позицию. Далее он соответствует после b. ab добавлен к результату. Затем он сопоставляет позицию после a, добавляет a в результирующий массив и переходит к следующей позиции, чтобы найти совпадение. И так далее. С (?=a+) процесс неопределенный, он просто сопоставляет 1+ a, но все же проверяет каждую позицию.

Чтобы разделить babaacaaa, вам понадобится

var s = 'babaacaaa';
console.info(
  s.split(/(a+[^a]*)/).filter(Boolean)
);

Соответствует a+[^a]*

  • a+ - 1 или более a
  • [^a]* - 0 или более символов, кроме a

Группа захвата позволяет добавлять совпавшие подстроки в результирующий массив split, а .filter(Boolean) отбрасывает пустые совпадения между соседними совпадениями.

string.match(/^[^a]+|a+[^a]*/g) вроде работает как положено.

Другие вопросы по теме