Регулярное выражение — начинается с определенной строки, но не заканчивается другой подстрокой

#javascript #regex #ruby

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

Вопрос:

Учитывая две строки s1 и s2 , я пытаюсь написать регулярное выражение, которое будет соответствовать строке, которая начинается с s1 , но не заканчивается s2

Пример (s1=TEST, s2=BAD)

  • ТЕСТ-101 совпадение
  • ПРОВЕРКА соответствия НЕКОТОРОМУ описанию
  • TEST-101-BAD не должен совпадать
  • TEST-SOME-DESC-BAD не должен совпадать

Вот что я пробовал для этого примера, но это не работает: /^TEST-.*((?!ПЛОХО))$/

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

1. @CarySwoveland Спасибо за ваше предложение, я улучшил вопрос в соответствии с вашим предложением

2. Намного лучше. Как насчет "TEST-101-SINBAD" ? ( Синдбад известен как мореход.)

3. Я знаю, что принятое решение не будет выполнено для «TEST-101-SINBAD» (поскольку я бы хотел, чтобы оно не совпадало). Но у меня появилась идея, как написать мое фактическое регулярное выражение.

4. Если бы вы изменили регулярное выражение на /^(?!. bBAD$)TEST-.*/ , b являющееся разрывом слов, "TEST-101-SINBAD" было бы принято.

Ответ №1:

Попробуйте это:

 /^(?!. BAD$)TEST-.*/
  

Это соответствует началу, продолжается и отклоняет все, что заканчивается на неверную строку, затем соответствует желаемому шаблону.

Вот демо, которое проходит все четыре ваших теста (нажмите «ВЫПОЛНИТЬ ТЕСТЫ» внизу, чтобы проверить).

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

1. Спасибо за быстрый ответ. Я не понимаю, почему отрицательный взгляд вперед находится в начале шаблона.

2. Проблема с размещением ее в конце в основном заключается в том, что там не будет ничего подходящего. Допустим, ваша строка TEST-101-BAD . В регулярном выражении, которое вы пробовали, ^TEST-.* фрагмент может соответствовать всей строке, включая BAD . Поскольку это правда, больше нет подходящих символов, поэтому (?!BAD) выполняется проверка. Затем есть конец строки ( $ ), и поэтому строка передается. То, что вы действительно хотите и идеально подходит для этой ситуации, — это «утверждение отрицательного взгляда назад» (см. Здесь ), но набор регулярных выражений JavaScript его не поддерживает.

Ответ №2:

Вы можете использовать startsWith и endsWith

 let arr = [`TEST-101`, `TEST-SOME-DESC`,`TEST-101-BAD`,`TEST-SOME-DESC-BAD`]

arr.forEach(e=>{
  console.log(e, e.startsWith('TEST') amp;amp; !e.endsWith('BAD'))
})  

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

1. Я ищу решение для чистого регулярного выражения

Ответ №3:

Использовать в JavaScript:

 /^TEST-(?!.*BAD$).*/
  

В Ruby:

 /ATEST-(?!.*BADz).*/
  

Смотрите доказательство регулярного выражения.

ОБЪЯСНЕНИЕ

 --------------------------------------------------------------------------------
  ^ / A                   the beginning of the string
--------------------------------------------------------------------------------
  TEST-                    'TEST-'
--------------------------------------------------------------------------------
  (?!                      look ahead to see if there is not:
--------------------------------------------------------------------------------
    .*                       any character except n (0 or more times
                             (matching the most amount possible))
--------------------------------------------------------------------------------
    BAD                      'BAD'
--------------------------------------------------------------------------------
    $ / z                   the end of the string
--------------------------------------------------------------------------------
  )                        end of look-ahead
--------------------------------------------------------------------------------
  .*                       any character except n (0 or more times
                           (matching the most amount possible))