Delphi: расширенные команды поиска строк

Kenneth - это строка. Допустим, он содержит 'justabcsome123texthaha'.

Я это уже знаю:

Чтобы найти текст:

if(pos('bcsome12',Kenneth) > 0) then

Чтобы проверить длину:

if(Length('Kenneth') > 10) then

Question 1:

Я хочу найти 'texthaha', но только если он находится в конце строки.

if(pos('texthaha',Kenneth) > 0) then

К сожалению, он найдет его где угодно, даже если он находится посередине. Есть простой способ?

Question 2:

Есть ли простой способ выполнить поиск, но с помощью * (любой символ между ними)?

Например, если я хочу найти bcsome1*3text, и мне все равно, какой символ у *. Я думаю, это называется подстановочным знаком, не так ли?

if(pos('bcsome1'*'3text',Kenneth) > 0) then

Я знаю, что это не работает. а есть ли аналогичный способ? Изменить: Может быть важно: ** Используемая версия Delphi очень старая, не уверен в версии, но это с 2006 года.

Regex (TRegex в современном Delphis), безусловно, может достичь ваших целей, но может быть немного излишним для ваших случаев.

Sebastian Proske 10.08.2018 15:34

По крайней мере, для первой части вашего вопроса вы можете посмотреть System.StrUtils.

nil 10.08.2018 15:54

Конечно, вы можете делать математику, если знаете позицию начала матча и длину двух строк?

David Heffernan 10.08.2018 18:21

Попробуйте выбрать в меню «Справка» -> «О нас».

Sertac Akyuz 10.08.2018 19:54

это отдельная программа, написанная на delphi, поэтому я не могу использовать ее, чтобы проверить версию, извините. но, как я сказал с 2006 года, он старый и не имеет всего

Linda Borandaz 10.08.2018 20:24

Вы пробовали думать о математике, которая здесь задействована?

David Heffernan 10.08.2018 20:48

@DavidHeffernan, вы имеете в виду if Pos(Sub, S) = Length(S) - Length(Sub) + 1, верно? Я на самом деле думал об этом, потому что не понимаю, почему нужно добавить +1 в конце, потому что я думал, что без +1

Linda Borandaz 10.08.2018 23:21

Nevermind понял это. не считайте символы раньше, вместо этого посмотрите, где начинается поисковый текст, поэтому ему нужно +1. Спасибо вам всем

Linda Borandaz 11.08.2018 00:04

Хорошо, я рад, что ты смог решить это сам

David Heffernan 11.08.2018 08:54
2
9
756
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Чтобы получить последнее вхождение, попробуйте LastDelimiter (см. помощь). Для подстановочных знаков см. Этот сообщение.

Относительно ответа с подстановочными знаками: я пробовал команду TRegEx с if TRegEx.IsMatch('abcdef', 'abcd.f') then ... Это дает мне эту ошибку: Ошибка: необъявленный идентификатор: TRegEx Значит, используемая версия delphi, вероятно, слишком старая и не имеет ее. ** Есть ли альтернатива? **

Linda Borandaz 10.08.2018 16:10

Всегда рекомендуется указывать версию Delphi в вопросе или тегах.

Uwe Raabe 10.08.2018 18:18

я не знаю точной версии, но это очень старая версия delphi, используемая с 2006 года. Поэтому мне нужно найти простые альтернативные способы. Итак, для первого вопроса я подумал о том, чтобы «смотреть вправо от найденного текста», и если там ничего нет, потому что это конец (строки Kenneth), то вы знаете, что искомый texthaha находится в конце нить.

Linda Borandaz 10.08.2018 18:48

LastDelimiter проверяет каждый символ в предоставленных вами разделителях, а не то, что запрашивается. По опубликованной вами ссылке: «Delimiters - это строка, в которой каждый символ является допустимым разделителем»..

Sertac Akyuz 10.08.2018 19:52

@SertacAkyuz спасибо за исправление, вы правы.

Felipe Morais 10.08.2018 19:59
Ответ принят как подходящий

В модуле EndsStr() есть функции EndsText() и StrUtils (последняя не чувствительна к регистру)

Но вы легко можете обеспечить необходимую функциональность с помощью известных функций (Pos также имеет перегруженную версию с третьим параметром в свежем Delphi):

NPos =  Length(S) - Length(Sub) + 1;
if PosEx(Sub, S, NPos) = NPos then...

или вариант, предложенный @Sertac Akyuz:

if Copy(S, NPos, Length(Sub)) = Sub ...

Вторую проблему можно решить с помощью функции типа MatchesMask()

 if MatchesMask(Kenneth, '*bcsome1*3text*')...

Аналогичный подход заключался бы в использовании TStringHelper, объявленном в SysUtils, и записи Кеннет.EndsWith ('texthaha')

Uwe Raabe 10.08.2018 18:17

Для известных функций Копировать будет лучшим тестом, поскольку любой шаблон можно найти в строке несколько раз.

Sertac Akyuz 10.08.2018 19:44

Замечательно для первого вопроса if Pos(Sub, S) = Length(S) - Length(Sub) + 1 then ... прекрасно работает, чтобы определить, находится ли он в конце строки (хотя я все еще пытаюсь понять логику, стоящую за этим, lol). Что касается второго вопроса, команда MatchesMask не может использоваться, я думаю, потому что используемая версия Delphi, вероятно, слишком старая, она с 2006 года, поэтому мне нужно найти обходной путь, если это возможно для MatchesMask

Linda Borandaz 10.08.2018 19:56

MatchesMask - довольно старая функция. Вы включили Masks в свой uses?

MBo 10.08.2018 19:58

Также обратите внимание на примечание @Sertac Akyuz о возможных множественных вхождениях подстроки - поэтому я изменил код на PosEx

MBo 10.08.2018 20:00

Когда я накладываю маски; при использовании я получаю сообщение «Ошибка: ожидается объявление, но найден идентификатор« Маски »». С PosEx я получаю «Ошибка: необъявленный идентификатор: 'PosEx'». Видимо из-за того, что использовалась старая версия. Pos работает, так что это хорошо

Linda Borandaz 10.08.2018 20:45

Ваш модуль содержит (обычно длинное) предложение uses вверху. Добавьте туда маски.

MBo 10.08.2018 20:50

@Linda Все, что было предложено вам к использованию (блоки масок и структур), существовало уже в 2002 году, может быть, даже раньше. Если у вас их нет, это может означать только то, что у вас нелегальная версия Warez.

Tom Brunberg 10.08.2018 21:37

спасибо MBo и tom. Это хорошо знать. Я попытался добавить маски к использованию, и это дает мне Fatal: File not found: 'Masks.dcu', вероятно, потому, что он не включен, теперь имеет смысл. @tom это просто основано на delphi.

Linda Borandaz 10.08.2018 22:46

Другие вопросы по теме