Список строк.indexOf: подстановочный знак внутри indexof?

#delphi #indexof

#delphi #indexof

Вопрос:

Я хочу получить номер строки в списке строк (загруженный из файла). Indexof, похоже, точно совпадает. Есть ли способ получить строку с подстановочным знаком-версией Indexof? что-то вроде SL.Indexof(‘?sometext’)?

Спасибо!

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

1. @David заголовок изменился, но содержимое осталось тем же. Ваш ответ все еще действителен.

2. @johnny, TStrings — более подходящее имя класса. @martin, TStrings — это класс очень низкого уровня, предназначенный для очень простой обработки строк, подобной массиву. Перегружать его регулярным выражением в стиле командной строки идеологически некорректно.

3. @user759588, вопрос касается TStringList, а не просто любого разработчика TStrings.

4. @johnny, indexOf — это функциональность TStrings. Все используют вместо этого TStringList, потому что TStrings — это абстрактный класс.

5. @Downvoter, я знаю, я проверил. Тем не менее, я подумал, что было бы легче следовать, если бы в названии и вопросе использовались одни и те же слова.

Ответ №1:

Если вы хотите сопоставить некоторую часть строки без каких-либо причудливых подстановочных знаков, как вы указываете в комментарии к другому ответу, то вы можете использовать простую функцию, подобную этой:

 function FindMatchStr(Strings: TStrings; const SubStr: string): Integer;
begin    
  for Result := 0 to Strings.Count-1 do
    if ContainsStr(Strings[Result], SubStr) then
      exit;
  Result := -1;
end;
  

Если вам нужно соответствие без учета регистра, вы можете использовать это:

 function FindMatchText(Strings: TStrings; const SubStr: string): Integer;
begin    
  for Result := 0 to Strings.Count-1 do
    if ContainsText(Strings[Result], SubStr) then
      exit;
  Result := -1;
end;
  

ContainsStr и ContainsText определены в StrUtils модуле RTL и следуют стандартному соглашению Str для обозначения сравнения с учетом регистра и Text для указания на отсутствие учета регистра.

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

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

2. мартин, вы когда-нибудь смотрели на реализацию indexOf? Игнорирование случая, когда список строк отсортирован (что в любом случае не помогло бы вам с вашим частичным совпадением) indexOf внутренне выполняет точно то же самое, перебирает все строки и сравнивает.

Ответ №2:

Там нет встроенного способа поиска TStringList подстановочных знаков. Вам необходимо использовать стороннюю библиотеку, такую как TPerlRegEx для регулярных выражений.

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

1. Или используйте встроенную поддержку регулярных выражений в Delphi XE

2. @Zruty: Я думаю, что есть достаточно людей, не использующих XE, чтобы сделать ваш ответ полезным ( 1). Кроме того, в OP не упоминается конкретная версия Delphi.

3. Мне действительно не нужны подстановочные знаки. Также было бы неплохо, если бы indexof соответствовал некоторой части строки…

4. @David: Я знаю 🙂 Я бы тоже проголосовал за вас, если бы это был ответ.

5. @martin: Если вам не нужны подстановочные знаки, вы можете использовать функцию Pos RTL, чтобы проверить, содержит ли строка подстроку, которую вы ищете. Конечно, вы не можете использовать indexOf, но должны выполнять итерации по строкам самостоятельно…

Ответ №3:

Адаптируя ответ Дэвида Хеффернана для использования с TStringList, функция могла бы выглядеть следующим образом:

 function Util_StrLst_GetLineFromSubstr(iStrlst: TStringList; iSubstr: string): Integer;
begin
  for Result := 0 to iStrlst.Count-1 do
    if (Pos(iSubstr, iStrlst[Result]) > 0) then
      Exit;
  Result := -1;
end;