Все объекты гарантированно имеют метод .equals()
, поскольку Object содержит метод, .equals()
, который возвращает логическое значение. Задача подкласса переопределять этот метод, если требуется дополнительное определение определения. Без него (т. Е. С помощью ==
) только адреса памяти проверяются между двумя объектами для равенства. String переопределяет этот метод .equals()
и вместо использования адреса памяти возвращает сравнение строк на уровне символа для равенства.
Ключевое замечание состоит в том, что строки хранятся в одном пуле, поэтому после создания строки он всегда хранится в программе по тому же адресу. Строки не меняются, они неизменяемы. Вот почему это плохая идея использовать регулярную конкатенацию строк, если у вас есть серьезное количество обработки строк. Вместо этого вы будете использовать предоставленные классы StringBuilder
. Помните, что указатели на эту строку могут измениться, и если вам было интересно увидеть, были ли два указателя одинаковыми ==
, это был бы прекрасный способ. Строки сами не делают.
Вы не даете нам язык, но если ваш аромат регулярного выражения поддерживает , посмотрите за утверждение , это то, что вам нужно:
.*(?<!a)$
(?<!a)
является отрицательное утверждение lookbehind, которое гарантирует, что до конца строки (или строки с модификатором m
) нет символа «a».
См. здесь здесь в Regexr
Вы также можете легко распространить это на другие символы, так как это проверка на строку и не является символьным классом.
.*(?<!ab)$
Это будет соответствовать тому, что не заканчивается с «ab», см. его в Regexr
Все, что совпадает с чем-то, заканчивающимся на --- .*a$
Итак, когда вы сопоставляете регулярное выражение, отрицайте это условие или, альтернативно, вы также можете делать .*[^a]$
, где [^a]
означает все, что есть not a
Используйте символ not (^
):
.*[^a]$
Если вы положите символ ^
в начале скобок, это означает «все, кроме вещей в скобках». $
является просто привязкой к концу.
Для нескольких символов просто поместите их все в свой собственный набор символов:
.*[^a][^b]$
Для поиска файлов, не заканчивающихся на «.tmp», мы используем следующее regex:
^(?!.*[.]tmp$).*$
. Протестировано с тегом Regex Tester дает следующий результат:
^.*(?![.]tmp$)
нет?
– Łukasz Zaroda
13 August 2017 в 19:48
.*
уже соответствует всей строке, поэтому оставшееся исключение больше не работает.
– FiveO
15 August 2017 в 19:25
Попробуйте это
/.*[^a]$/
. []
обозначает класс символов, а ^
инвертирует класс символов для соответствия всем, кроме a
.
.*[^a]$
приведенное выше выражение будет соответствовать строкам, которые не заканчиваются на a
.
Принятый ответ подходит, если вы можете использовать поисковые запросы. Однако существует и другой подход к решению этой проблемы.
Если мы посмотрим на широко предложенное регулярное выражение для этого вопроса:
.*[^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
Вопрос старый, но я не мог найти лучшего решения, которое я здесь размещаю. Найти все 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