Как указать концы строк и обратную логику в регулярном выражении? [Дубликат]

Все объекты гарантированно имеют метод .equals(), поскольку Object содержит метод, .equals(), который возвращает логическое значение. Задача подкласса переопределять этот метод, если требуется дополнительное определение определения. Без него (т. Е. С помощью ==) только адреса памяти проверяются между двумя объектами для равенства. String переопределяет этот метод .equals() и вместо использования адреса памяти возвращает сравнение строк на уровне символа для равенства.

Ключевое замечание состоит в том, что строки хранятся в одном пуле, поэтому после создания строки он всегда хранится в программе по тому же адресу. Строки не меняются, они неизменяемы. Вот почему это плохая идея использовать регулярную конкатенацию строк, если у вас есть серьезное количество обработки строк. Вместо этого вы будете использовать предоставленные классы StringBuilder. Помните, что указатели на эту строку могут измениться, и если вам было интересно увидеть, были ли два указателя одинаковыми ==, это был бы прекрасный способ. Строки сами не делают.

109
задан ArtB 1 November 2017 в 16:31
поделиться

8 ответов

Вы не даете нам язык, но если ваш аромат регулярного выражения поддерживает , посмотрите за утверждение , это то, что вам нужно:

.*(?<!a)$

(?<!a) является отрицательное утверждение lookbehind, которое гарантирует, что до конца строки (или строки с модификатором m) нет символа «a».

См. здесь здесь в Regexr

Вы также можете легко распространить это на другие символы, так как это проверка на строку и не является символьным классом.

.*(?<!ab)$

Это будет соответствовать тому, что не заканчивается с «ab», см. его в Regexr

136
ответ дан stema 17 August 2018 в 09:24
поделиться
  • 1
    Я тоже это пробовал! Почему RegexPAL дает другой результат? – Aquillo 6 May 2013 в 13:43
  • 2
    Я не знаю RegexPAL, но регулярные выражения различаются во всех языках, а утверждения lookbehind - это расширенная функция, которая не поддерживается всеми. – stema 6 May 2013 в 13:47
  • 3
    regexpal - это средство проверки регулярных выражений на основе javascript, и javascript не поддерживает утверждения lookbehind, которые грустны – HamZa 6 May 2013 в 13:58
  • 4
    Lookbehinds не поддерживаются в regexr (javascript) – Stealth Rabbi 19 January 2016 в 13:42
  • 5
    Отсутствие следов в JS заставляет меня плакать. Если вы делаете серверную часть, хотя вы, вероятно, можете использовать модуль PCRE на NPM или аналогичный, чтобы использовать их напрямую (это набор привязок, поэтому я не думаю, что вы можете использовать его front-end) – Eirik Birkeland 18 March 2016 в 14:16

Все, что совпадает с чем-то, заканчивающимся на --- .*a$ Итак, когда вы сопоставляете регулярное выражение, отрицайте это условие или, альтернативно, вы также можете делать .*[^a]$, где [^a] означает все, что есть not a

0
ответ дан Bill 17 August 2018 в 09:24
поделиться

Используйте символ not (^):

.*[^a]$

Если вы положите символ ^ в начале скобок, это означает «все, кроме вещей в скобках». $ является просто привязкой к концу.

Для нескольких символов просто поместите их все в свой собственный набор символов:

.*[^a][^b]$
45
ответ дан Community 17 August 2018 в 09:24
поделиться
  • 1
    +1, с оговоркой, что это не соответствует пустой строке (которая может или не может быть такой, как предполагалось), поэтому значение «скорее всего» любого символа, который не находится в скобках ». – Fred Foo 6 May 2013 в 13:12
  • 2
    @ 0A0D: строка, содержащая пробелы, не является пустой строкой. – Fred Foo 6 May 2013 в 13:19
  • 3
    @ 0A0D На самом деле, это не для обсуждения, это факт – Doorknob 6 May 2013 в 13:22
  • 4
    @Doorknob: это не соответствует ae или cb. – Fred Foo 6 May 2013 в 13:25
  • 5
    Nop, это не позволило бы "acb" или. – Aquillo 6 May 2013 в 13:26

Для поиска файлов, не заканчивающихся на «.tmp», мы используем следующее regex:

^(?!.*[.]tmp$).*$

. Протестировано с тегом Regex Tester дает следующий результат:

23
ответ дан FiveO 17 August 2018 в 09:24
поделиться
  • 1
    Это интересно, любая идея, почему это работает и почему ^.*(?![.]tmp$) нет? – Łukasz Zaroda 13 August 2017 в 19:48
  • 2
    Ваш ранний .* уже соответствует всей строке, поэтому оставшееся исключение больше не работает. – FiveO 15 August 2017 в 19:25
  • 3
    Это имеет смысл, спасибо :). – Łukasz Zaroda 15 August 2017 в 19:29
  • 4
    Для моих целей это сработало, а другие - нет. Благодаря! – David Moritz 14 December 2017 в 16:09

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

/.*[^a]$/

. [] обозначает класс символов, а ^ инвертирует класс символов для соответствия всем, кроме a.

3
ответ дан JesperE 17 August 2018 в 09:24
поделиться
.*[^a]$

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

7
ответ дан Kent 17 August 2018 в 09:24
поделиться
  • 1
    Я расширил свой вопрос, поскольку исходный пример, похоже, не полностью соответствовал моему делу. Вы можете решить это? – Aquillo 6 May 2013 в 13:30

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

Если мы посмотрим на широко предложенное регулярное выражение для этого вопроса:

.*[^a]$

Мы будем что он почти работает. Он не принимает пустую строку, которая может быть немного неудобной. Однако это небольшая проблема при работе с одним персонажем. Однако, если мы хотим исключить целую строку, например. "abc", то:

.*[^a][^b][^c]$

не будет работать. Например, он не принимает ac.

Однако для решения этой проблемы существует простое решение. Мы можем просто сказать:

.{,2}$|.*[^a][^b][^c]$

или более обобщенная версия:

.{,n-1}$|.*[^firstchar][^secondchar]$ где n - длина строки, которую вы хотите запретить (для abc это 3), а firstchar, secondchar, ... являются первыми, вторыми ... n-ыми символами вашей строки (для abc это будет a, затем b, затем c).

Это происходит из простого наблюдения, что строка, которая короче текста, которую мы не запретим, не может содержать этот текст по определению. Таким образом, мы можем либо принять все, что короче («ab» не «abc»), либо что-то достаточно длинное для нас, но без конца.

Вот пример поиска, который удалит все файлы, которые не являются .jpg:

find . -regex '.{,3}$|.*[^.][^j][^p][^g]$' -delete

0
ответ дан MatthewRock 17 August 2018 в 09:24
поделиться

Вопрос старый, но я не мог найти лучшего решения, которое я здесь размещаю. Найти все USB-накопители, но не перечислять разделы, тем самым удалив «часть [0-9]» из результатов. Я закончил делать два grep, последний отрицает результат:

ls -1 /dev/disk/by-path/* | grep -P "\-usb\-" | grep -vE "part[0-9]*$"

Это приводит к моей системе:

pci-0000:00:0b.0-usb-0:1:1.0-scsi-0:0:0:0

Если мне нужны только разделы, которые я мог бы сделать:

ls -1 /dev/disk/by-path/* | grep -P "\-usb\-" | grep -E "part[0-9]*$"

Где я получаю:

pci-0000:00:0b.0-usb-0:1:1.0-scsi-0:0:0:0-part1
pci-0000:00:0b.0-usb-0:1:1.0-scsi-0:0:0:0-part2

И когда я это делаю:

readlink -f /dev/disk/by-path/pci-0000:00:0b.0-usb-0:1:1.0-scsi-0:0:0:0

Я получаю:

/dev/sdb
0
ответ дан tombert 17 August 2018 в 09:24
поделиться
Другие вопросы по тегам:

Похожие вопросы: