Что нового

Поиск всех совпадений части фразы (слова) в массиве

DyadyaGenya

Знающий
Сообщения
300
Репутация
10
Добрый день. Давно не занимался autoit, подзабыл его. Не получается найти все нужные фразы в массиве. Находит только первое совпадение. Пробую так:
Код:
Global $aResultK[0]

_ArrayAdd($aResultK, "много букв фраза2")
_ArrayAdd($aResultK, "ещё больше фраза1")
_ArrayAdd($aResultK, "снова фраза1")
_ArrayAdd($aResultK, "уже фраза2")
_ArrayAdd($aResultK, "опять фраза1")
_ArrayAdd($aResultK, "а теперь фраза3")
_ArrayAdd($aResultK, "много буковок фраза3")
_ArrayAdd($aResultK, "ещё буковки фраза2")
_ArrayAdd($aResultK, "очень много текста фраза2")
_ArrayDisplay($aResultK)

Local $iIndex[UBound($aResultK)]
$sSearch = "фраза3"
For $i = 0 To UBound($aResultK)-1
$iIndex[$i] = _ArraySearch($aResultK, $sSearch, 0,0,0,1)
If @error Then
    ConsoleWrite("Не найдено " & $sSearch & " не был найден в массиве." & @CR)
Else
    ConsoleWrite("Найдено " & $sSearch & " найден в массиве в позиции " & $iIndex[$i] & "." & @CR)
EndIf
Next


и так
Код:
Global $aResultK[0]

_ArrayAdd($aResultK, "много букв фраза2")
_ArrayAdd($aResultK, "ещё больше фраза1")
_ArrayAdd($aResultK, "снова фраза1")
_ArrayAdd($aResultK, "уже фраза2")
_ArrayAdd($aResultK, "опять фраза1")
_ArrayAdd($aResultK, "а теперь фраза3")
_ArrayAdd($aResultK, "много буковок фраза3")
_ArrayAdd($aResultK, "ещё буковки фраза2")
_ArrayAdd($aResultK, "очень много текста фраза2")
_ArrayDisplay($aResultK)

$sSearch = "фраза2"
For $i = 0 To UBound($aResultK)-1
$iIndex = _ArraySearch($aResultK, $sSearch, 0,0,0,1)
If @error Then
    ConsoleWrite("Не найдено " & $sSearch & " не был найден в массиве." & @CR)
Else
    ConsoleWrite("Найдено " & $sSearch & " найден в массиве в позиции " & $iIndex & "." & @CR)
EndIf
Next
 

InnI

AutoIT Гуру
Сообщения
4,922
Репутация
1,432
Код:
#include <Array.au3>

Global $aResultK[0]

_ArrayAdd($aResultK, "много букв фраза2")
_ArrayAdd($aResultK, "ещё больше фраза1")
_ArrayAdd($aResultK, "снова фраза1")
_ArrayAdd($aResultK, "уже фраза2")
_ArrayAdd($aResultK, "опять фраза1")
_ArrayAdd($aResultK, "а теперь фраза3")
_ArrayAdd($aResultK, "много буковок фраза3")
_ArrayAdd($aResultK, "ещё буковки фраза2")
_ArrayAdd($aResultK, "очень много текста фраза2")
_ArrayDisplay($aResultK)

$sSearch = "фраза2"
$iCount = 0
For $i = 0 To UBound($aResultK) - 1
  If StringInStr($aResultK[$i], $sSearch) Then
    ConsoleWrite("Найдено: '" & $sSearch & "' найден в массиве в позиции " & $i & "." & @CR)
    $iCount += 1
  EndIf
Next
If $iCount Then
  ConsoleWrite("Количество совпадений: " & $iCount & @CR)
Else
  ConsoleWrite("Не найдено: '" & $sSearch & "' не был найден в массиве." & @CR)
EndIf
 

Andrey_A

Продвинутый
Сообщения
323
Репутация
68
или так:
Код:
#include <Array.au3>

Global $aResultK[0]
_ArrayAdd($aResultK,'много букв фраза2')
_ArrayAdd($aResultK,'ещё больше фраза1')
_ArrayAdd($aResultK,'снова фраза1')
_ArrayAdd($aResultK,'уже фраза2')
_ArrayAdd($aResultK,'опять фраза1')
_ArrayAdd($aResultK,'а теперь фраза3')
_ArrayAdd($aResultK,'много буковок фраза3')
_ArrayAdd($aResultK,'ещё буковки фраза2')
_ArrayAdd($aResultK,'очень много текста фраза2')
; _ArrayDisplay($aResultK)
$sSearch='фраза2'
$iCount=0
$sText=_ArrayToString($aResultK,@CRLF)
$aRes=StringRegExp($sText,'(?m)^(.*\Q'&$sSearch&'\E.*)$',3)
If IsArray($aRes)Then
  _ArrayDisplay($aRes)
  $iCount=UBound($aRes)
EndIf
MsgBox(4096,'Переменная $iCount','Количество совпадений: '&$iCount)
 

Norm

Продвинутый
Сообщения
278
Репутация
74
Или просто использовать функцию _ArrayFindAll()
 
Автор
D

DyadyaGenya

Знающий
Сообщения
300
Репутация
10
Или просто использовать функцию _ArrayFindAll()
Так она ж вроде ищет всю строку, а не часть строки. Вот, напр, в справке такой пример:
Код:
[URL='https://autoit-script.ru/docs/libfunctions/autoit3.chm../keywords/include.htm']#include[/URL] <Array.au3>

[URL='https://autoit-script.ru/docs/libfunctions/autoit3.chm../keywords/dim.htm']Local[/URL] $avArray[5] = ['aa', 'bb', 'cc', 'bb', 'aa']
[URL='https://autoit-script.ru/docs/libfunctions/_arraydisplay.htm']_ArrayDisplay[/URL]($avArray, "Поиск 'aa'") ; Просмотр массива, в котором поиск
[URL='https://autoit-script.ru/docs/libfunctions/autoit3.chm../keywords/dim.htm']Local[/URL] $aiResult [URL='https://autoit-script.ru/docs/libfunctions/autoit3.chm../intro/lang_operators.htm']=[/URL] [URL='https://autoit-script.ru/docs/libfunctions/_arrayfindall.htm']_ArrayFindAll[/URL]($avArray, 'aa') ; Поиск всех
[URL='https://autoit-script.ru/docs/libfunctions/_arraydisplay.htm']_ArrayDisplay[/URL]($aiResult, "Индексы") ; Результаты поиска 'aa' в массиве $avArray

Замените в поиске "aa" на "a" и ничего не найдет.
Сообщение автоматически объединено:

Интересный вариант. А если массив не одномерный? Напр. такой:
Код:
_ArrayAdd($aResultK,'много букв фраза2' & '|' & 'ответ1')
_ArrayAdd($aResultK,'ещё больше фраза1' & '|' & 'ответ2')
_ArrayAdd($aResultK,'снова фраза1' & '|' & 'ответ4')
_ArrayAdd($aResultK,'уже фраза2' & '|' & 'ответ3')
_ArrayAdd($aResultK,'опять фраза1' & '|' & 'ответ1')
_ArrayAdd($aResultK,'а теперь фраза3' & '|' & 'ответ5')
_ArrayAdd($aResultK,'много буковок фраза3' & '|' & 'ответ1')
_ArrayAdd($aResultK,'ещё буковки фраза2' & '|' & 'ответ7')
_ArrayAdd($aResultK,'очень много текста фраза2' & '|' & 'ответ10')

Оно то ищет, но мне потом искать "совпадения" (сколько на каждую искомую фразу приходится каких ответов) по полной строке во второй её части
Чтоб получилось:
фраза1 с ответом1 встречается столько-то раз фраза1 с ответом2 встречается столько-то раз фраза1 с ответом3 встречается столько-то раз .................................. фраза1 с ответом10 встречается столько-то раз фраза2 с ответом1 встречается столько-то раз .................................. фраза3 с ответом10 встречается столько-то раз
 
Последнее редактирование:

Norm

Продвинутый
Сообщения
278
Репутация
74
Так она ж вроде ищет всю строку, а не часть строки. Вот, напр, в справке такой пример:
Посмотрите повнимательнее
$iCompare
Код:
Local $aResultK[0]

_ArrayAdd($aResultK, "много букв фраза2")
_ArrayAdd($aResultK, "ещё больше фраза1")
_ArrayAdd($aResultK, "снова фраза1")
_ArrayAdd($aResultK, "уже фраза2")
_ArrayAdd($aResultK, "опять фраза1")
_ArrayAdd($aResultK, "а теперь фраза3")
_ArrayAdd($aResultK, "много буковок фраза3")
_ArrayAdd($aResultK, "ещё буковки фраза2")
_ArrayAdd($aResultK, "очень много текста фраза2")
_ArrayDisplay($aResultK)

Local $sSearch = "фраза3"
Local $iIndex = _ArrayFindAll($aResultK, $sSearch, 0, 0, 0, 1)


MsgBox(0, Default, '"'& $sSearch & '" найден в массиве в '& UBound($iIndex) &" строках")
If IsArray($iIndex) Then
    _ArrayDisplay($iIndex, $sSearch, " найден(ы) в:")
EndIf
Замените в поиске "aa" на "a" и ничего не найдет.
Код:
Local $avArray[5] = ['aafff', 'bbtttt', 'ccuuu', 'bbkkkk', 'aaffff']
_ArrayDisplay($avArray, 'aa') ; Просмотр массива, в котором поиск
Local $iIndex =_ArrayFindAll($avArray, 'aa', 0, 0, 0, 1) ; Поиск всех
_ArrayDisplay($iIndex, "аа") ; Результаты поиска 'aa' в массиве $avArray

Local $iIndex =_ArrayFindAll($avArray, 'a', 0, 0, 0, 1) ; Поиск всех
_ArrayDisplay($iIndex, 'а') ; Результаты поиска 'a' в массиве $avArray
Оно то ищет, но мне потом искать "совпадения" (сколько на каждую искомую фразу приходится каких ответов) по полной строке во второй её части
Чтоб получилось:
фраза1 с ответом1 встречается столько-то раз фраза1 с ответом2 встречается столько-то раз фраза1 с ответом3 встречается столько-то раз .................................. фраза1 с ответом10 встречается столько-то раз фраза2 с ответом1 встречается столько-то раз .................................. фраза3 с ответом10 встречается столько-то раз
Для этого _ArrayFindAll тоже подойдёт. Если сначала найти индексы со всеми "фразами", а затем их перебрать их в цикле для поиска повторений.
Но лучще воспользуйтесь примерам от InnI описанными выше.
В цикле (в любом случае) придется использовать StringRegExp() с флагом 3 из которой, затем получите количество повторов через UBound()
или более короткий "костыль" в одну строку через StringReplace() или StringRegExpReplace() которые вернут @extended с числом найденных и (как бы) заменённых "фраз".


 
Последнее редактирование:
Автор
D

DyadyaGenya

Знающий
Сообщения
300
Репутация
10
Посмотрите повнимательнее
$iCompare
Как-то не обратил внимание. Работает.
Но лучще воспользуйтесь примерам от InnI описанными выше.
В принципе с ним и работаю, но даже StringRegExp() с флагом 3 пока не помогает сделать так, как мне надо. (Где-то не дорабатываю)
 

Norm

Продвинутый
Сообщения
278
Репутация
74
Самое простое решение, при условии, что построение строки соответствует примеру.
Код:
Local $sRegex = "фраза2"
Local $sString = "много букв фраза2 много букв фраза2 много букв фраза2"
StringReplace($sString, $sRegex, "")
MsgBox(0, "Result", "В этой строке найдено "& @extended &" совпадения")
 
Последнее редактирование:
Автор
D

DyadyaGenya

Знающий
Сообщения
300
Репутация
10
Самое простое решение, при условии, что построение строки соответствует примеру.
Проблема в том, что в полученном в конце концов массиве не понятно как искать совпадения, потому что нет фразы для поиска. Это фактически повторы строк. Но это видимо тема для новой темы, раз у самого до сих пор не получилось.
 

Norm

Продвинутый
Сообщения
278
Репутация
74
Тогда и искать не нужно, а просто идти дальше и пропустить строку без искомой фразы.
Код:
If $sSearch = "" Then
      ContinueLoop
EndIf
 
Верх