#javascript #regex
#javascript #регулярное выражение
Вопрос:
Я пытаюсь создать регулярное выражение JS, которое соответствует !next
либо в начале, либо в конце строки.
В настоящее время я использую /(^!next|!next$)/i
, который работает. Однако это, очевидно, некрасиво для чтения, а не для сушки, поэтому я ищу улучшения.
Самое близкое, к чему я пришел, это:
/(?=!next)[^$]/i
Но на самом деле это просто соответствует всему (и теперь мне приходит в голову, что я неправильно запомнил способ, который ^
работает внутри классов символов, так что это решение в любом случае является мусором).
Я искал в Интернете и ТАК ДАЛЕЕ, и я совершенно в тупике.
Комментарии:
1. Вы могли бы оставить эти круглые скобки, но ваше первое выражение просто отлично.
^
внутри[]
означает не какой-либо один символ.2. Первоначальный способ намного проще понять с первого взгляда. Если есть другие разработчики, я бы придерживался этого.
3. Вы могли бы динамически создавать регулярное выражение с
function beginningOrEnd(str) { return new Regexp(`^${str}|${str}$`, 'i'); }
помощью, а затем вызывать его сbeginningOrEnd("!next")
помощью .4. Почему вы избегаете восклицательного знака?
5. @torazaburo хороший вопрос. он основан на регулярном выражении, автором которого был кто-то другой в PR, и я скопировал его, не заметив.
Ответ №1:
Вот забавный вариант, использующий условные выражения регулярных выражений:
/(^)?!next(?(1)|$)/gm
Как это работает, оно фиксирует привязку к началу строки и, если ее нет, сопоставляет привязку к концу строки.
Лично я бы все же высказался в пользу вашего решения, а не моего, потому что оно более читабельно для тех, кто не обладает чрезвычайно глубокими знаниями регулярных выражений (и более переносимо).
Для дополнительного удовольствия, вот другая версия (это еще уродливее, чем ваш первоначальный вариант):
/!next(?:(?<=^.{5})|(?=$))/gm
Тем не менее, я бы все же рекомендовал придерживаться классического чередования.
И, наконец, тот, который работает в JS (нет, на самом деле):
/(?:^|(?=.{5}$))!next/gm
Комментарии:
1. Я не тестировал его, но я готов поспорить, что первоначальный способ OP технологически быстрее.
2. @PHPglue: согласно регулярному выражению 101, вы правы (58 шагов против 86) , но OP запросил СУХОЕ регулярное выражение, а не быстрое. Обратите внимание, что я выступаю за его решение, а не за свое собственное. Мне действительно интересно, почему вариант чередования теперь имеет меньше шагов…
3. Я не могу заставить это работать в regexp101, указывая вкус JS.
4. @SebastianLenartowicz второе … действительно ужасно. но приятно: P
5. @torazaburo. Нет. JavaScript не поддерживает условные выражения. Вторая версия также не работает, потому что JS также не поддерживает утверждения lookbehind .
Ответ №2:
Вы могли бы попробовать
function beginningOrEnd(input, search) {
const pos = input.search(search);
return pos === 0 || pos === input.length - search.length;
}
beginningOrEnd("hey, !help", "!help");
Это использует search.length
, поэтому, очевидно search
, должна быть строка.
Или вы можете создать регулярное выражение самостоятельно:
function beginningOrEnd(search) {
return new RegExp(`^${search}|${search}$`, "i");
}
beginningOrEnd("!help").test(input)
В реальном мире, конечно, вам нужно соответствующим образом экранировать специальные символы регулярных выражений.
Комментарии:
1. Очень приятно. Очевидно, что первая версия работает только в том случае, если вы ограничиваетесь
search
литеральными строками, а не регулярными выражениями.