JS Regex: удалить что-либо (ТОЛЬКО) после слова

#javascript #regex

#javascript #регулярное выражение

Вопрос:

Я хочу удалить все символы (символ зависит от того, что я выбираю в данный момент) после каждого слова, не зная, каким может быть слово. Но оставьте их перед каждым словом.

Пара примеров:

!!hello! my! !!name!!! is !!bob!! должно вернуться…

!!hello my !!name is !!bob ; для !

и

$remove$ the$ targetted$@ $$symbol$$@ only $after$ a $word$ должно вернуться…

$remove the targetted@ $$symbol@ only $after a $word ; для $

Комментарии:

1. И вы пробовали … что?

Ответ №1:

Вам нужно использовать группы захвата и заменить:

 "!!hello! my! !!name!!! is !!bob!!".replace(/([a-zA-Z] )(! )/g, '$1');
  

Что работает для вашей тестовой строки. Для работы с любым общим символом или группой символов:

 var stripTrailing = trail => {
  let regex = new RegExp(`([a-zA-Z0-9] )(${trail} )`, 'g');
  return str => str.replace(regex, '$1');
};
  

Обратите внимание, что это не выполняется для любых символов, которые имеют значение в регулярном выражении: []{} *^$. и т.д. Экранирование их программно оставлено в качестве упражнения для читателя.

Обновить

Согласно вашему комментарию, я подумал, что объяснение может вам помочь, поэтому:

Во-первых, в этом случае невозможно заменить только часть совпадения, вы должны заменить все совпадение. Итак, нам нужно найти соответствующий шаблон, разделить его на ту часть, которую мы хотим сохранить, и ту часть, которую мы не хотим, и заменить все совпадение той его частью, которую мы хотим сохранить. Итак, давайте разберем мое регулярное выражение выше на несколько строк, чтобы посмотреть, что происходит:

Сначала мы хотим сопоставить любое количество последовательных буквенно-цифровых символов, это будет «слово», из которого будет удален конечный символ:

 (       // denotes capturing group for the 'word'
  [     // [] means 'match any character listed inside brackets'
    a-z // list of alpha character a-z
    A-Z // same as above but capitalized
    0-9 // list of digits 0 to 9
  ]     // plus means one or more times
)
  

Группа захвата означает, что мы хотим иметь доступ только к этой части соответствия.
Тогда у нас есть другая группа

 (
  ! // I used ES6's string interpolation to insert the arg here
    // match that exclamation (or whatever) one or more times
)
  

Затем мы добавляем g флаг, чтобы замена выполнялась для каждого совпадения в целевой строке без флага, который он возвращает после первого совпадения. JavaScript предоставляет удобное сокращение для доступа к группам захвата в виде автоматически интерполируемых символов, ‘$ 1’ выше означает ‘вставить содержимое первой группы захвата здесь, в этой строке’.

Итак, в приведенном выше примере, если вы заменили ‘$ 1’ на ‘$ 1 $ 2’, вы увидите ту же строку, с которой начали, если вы сделали ‘foo $ 2’, вы увидите foo вместо каждого слова, сопровождаемого одним или несколькими ! и т.д.

Комментарии:

1. Отлично, спасибо. Где вы научились своим «навыкам регулярных выражений»? Хотите улучшить мое.

2. В основном здесь, на SO, так что вы на правильном пути. «Выучить регулярное выражение трудным путем» Зеда Шоу — хороший ресурс. Но лучше всего перейти на сайт, подобный regex101, и начать воспроизведение, потому что он дает вам объяснение регулярного выражения. regex101.com/r/tvGQ64/1

3. @Kreitzo добавил объяснение к ответу, надеюсь, это поможет вам на пути.

4. Разве здесь нельзя использовать положительные прогнозы?

5. @GGG Я так не думаю, было бы неплохо посмотреть, чтобы сопоставить слово после сопоставления! и JS не может выполнять поисковые запросы. Я поиграл с этим и не заставил его работать, не стесняйтесь публиковать альтернативный ответ.