Что нового

Найти количество слов\выражений в тексте с помощью RegExp

Fever

Скриптер
Сообщения
308
Репутация
112
Здравствуйте, уважаемые участники сообщества. :bye:

Прошу помощи в нахождении количества совпадений в тексте с помощью регулярных выражений, сам в них не силен. И ещё вопрос, какой способ будет быстрее: регулярки или строковые функции?
 

Redline

AutoIT Гуру
Сообщения
506
Репутация
369
Первый массив выдаст совпадения по сочетанию 'string1 text'
Второй по слову 'string1'
Код:
#include <Array.au3>
$sText = 'string1 text text' & @CRLF & 'string2 text2' & @CRLF & 'text string1 text' & @CRLF & 'string1'
$aResult2Word = StringRegExp($sText, '(?i)string1\stext', 3)
_ArrayDisplay($aResult2Word)
ConsoleWrite(UBound($aResult2Word) & @CRLF)
$aResult1Word = StringRegExp($sText, '(?i)string1', 3)
_ArrayDisplay($aResult1Word)
ConsoleWrite(UBound($aResult1Word) & @CRLF)

Ну а количество совпадений - это размер массива
 
Автор
F

Fever

Скриптер
Сообщения
308
Репутация
112
Redline, спасибо за решение :IL_AutoIt_1:
 

gregaz

AutoIT Гуру
Сообщения
1 166
Репутация
299
По крайней мере проще с помощью регулярных выражений:

Я думаю надо использовать метасимволы \Q и \E
Для возможности поиска фрагмента со спец. символами

Код:
#include <Array.au3>
$sText= "#include-once" &  _ 
            "#include <WindowsConstants.au3>" &  _ 
            "#include <GUICon(stantsEx.au3>" &  _ 
            "#include <StaticCon(stants.au3> " &  _ 
            "#include <Array.au3>"
$sFind="Con(st"
$aRez=StringRegExp($sText, "\Q" & $sFind & "\E", 3)
_ArrayDisplay($aRez)
MsgBox(0,'Инфо','Найдено совпадений : ' & UBound($aRez))
 
Автор
F

Fever

Скриптер
Сообщения
308
Репутация
112
gregaz, спасибо за ответ :IL_AutoIt_1:
 

gregaz

AutoIT Гуру
Сообщения
1 166
Репутация
299
Garrett [?]
Для этих целей есть специальный раздел!
Надо бы переместить, иначе опять будет повторяться тема. Ведь подобное уже было где-то
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8 473
Репутация
2 403
Перенёс, также и все остальные темы по RegExp.
 

AZJIO

Меценат
Меценат
Сообщения
2 752
Репутация
1 149
я так всегда использовал

Код:
$sText= "#include-once" &  _
            "#include <WindowsConstants.au3>" &  _
            "#include <GUICon(stantsEx.au3>" &  _
            "#include <StaticCon(stants.au3> " &  _
            "#include <Array.au3>"
$sFind="Con(st"
StringRegExpReplace($sText, "\Q" & $sFind & "\E", '')
If Not @error Then MsgBox(0,'Инфо','Найдено совпадений : ' & @extended)
 

AZJIO

Меценат
Меценат
Сообщения
2 752
Репутация
1 149
gregaz
Откуда такие данные? Проверил, StringRegExpReplace сработал быстрее, использовал файл 10Мб. Движок тот же, но один вариант создаёт массив а второй просто удаляет текст, не вижу с какой стати StringRegExp будет быстрее.
 

gregaz

AutoIT Гуру
Сообщения
1 166
Репутация
299
AZJIO [?]
Откуда такие данные?
Здесь в какой-то из тем уже проводились подобные эксперименты. Тогда меня убедили в этом.
Все зависит не только от размера файла но и от количества совпадающих элементов.
Причем было высказано утверждение, что StringRegExpReplace в себе использует предварительный StringRegExp
 

AZJIO

Меценат
Меценат
Сообщения
2 752
Репутация
1 149
gregaz
Количество совпадений тоже самое. Проверил поиск длинного слова с меньшим количеством совпадений, StringRegExp выйграл. Видимо он проигрывал при поиске буквы "а" по причине создания большого массива 128000 элементов.
 

Redline

AutoIT Гуру
Сообщения
506
Репутация
369
Оказывается стандартный StringReplace тоже возвращает количество замен:
Код:
$sText = '#include-once' & _
		'#include <WindowsConstants.au3>' & _
		'#include <GUICon(stantsEx.au3>' & _
		'#include <StaticCon(stants.au3> ' & _
		'#include <Array.au3>'
$sFind = 'Con(st'
StringReplace($sText, $sFind, '')
ConsoleWrite(@extended & @CRLF)
 

gregaz

AutoIT Гуру
Сообщения
1 166
Репутация
299
Redline [?]
Оказывается стандартный StringReplace тоже возвращает количество замен:
Конечно, но он неприменим , если $sFind - есть шаблон
А вопрос автора темы насчет скорости касался именно этой ф-ии
 

madmasles

Модератор
Глобальный модератор
Сообщения
7 790
Репутация
2 319
gregaz [?]
но он неприменим , если $sFind - есть шаблон
Если шаблон такой: "\Q" & $sFind & "\E", то, ИМХО, применим. :smile:
И в этом случае у меня StringReplace() быстрее всех:
Сначала пишем произвольный файл:
Код:
Dim $aArray[1000001] = [1000000]
$sText = ''
For $i = 1 To $aArray[0]
	$sText &= (Chr(Random(65, 90, 1)) & Chr(Random(97, 122, 1)) & @CRLF)
Next
$hFile = FileOpen(@ScriptDir & '\test.txt', 2)
FileWrite($hFile, $sText)
FileClose($hFile)

Потом его проверяем:
Код:
$sFind = 'Zz'

$hFile = FileOpen(@ScriptDir & '\test.txt')
$sText = FileRead($hFile)
FileClose($hFile)

$iStart = TimerInit()
StringReplace($sText, $sFind, '', 0, 1)
$iExt = @extended
$sTime = StringFormat('%.2f ms', TimerDiff($iStart))
MsgBox(0, 'StringReplace', $sTime & ', Совпадений: ' & $iExt)

$iStart = TimerInit()
$aRez = StringRegExp($sText, '\Q' & $sFind & '\E', 3)
$sTime = StringFormat('%.2f ms', TimerDiff($iStart))
MsgBox(0, 'StringRegExp', $sTime & ', Совпадений: ' & UBound($aRez))

$iStart = TimerInit()
StringRegExpReplace($sText, '\Q' & $sFind & '\E', '')
$iExt = @extended
$sTime = StringFormat('%.2f ms', TimerDiff($iStart))
MsgBox(0, 'StringRegExpReplace', $sTime & ', Совпадений: ' & $iExt)
 

gregaz

AutoIT Гуру
Сообщения
1 166
Репутация
299
Re: Найти количество слов\\выражений в тексте с помощью RegExp

madmasles [?]
Если шаблон такой: "\Q" & $sFind & "\E", то, ИМХО, применим.
Обрати внимание :
Я сказал : если $sFind - есть шаблон

Подразумевал :
Код:
$sFind='Con.*st'
; $sFind - есть шаблон
а
Код:
$sFind='Con(st'
$sFind - есть фрагмент текста

Поэтому : если искать совпадения фрагмента текста , конечно следует использовать StringReplace


Добавлено:
Сообщение автоматически объединено:

madmasles
Если не трудно ?
Поскольку ты проанализировал варианты, может быть обобщишь и сделаешь выводы .
Когда лучше что применять.
Чтобы уже "устаканить" эту тему раз и навсегда.
 

madmasles

Модератор
Глобальный модератор
Сообщения
7 790
Репутация
2 319
gregaz,
Так все уже в теме есть.
Если искать количество вхождений конкретного текста, то быстрее всего StringReplace(), если искать по шаблону, то быстрее StringRegExp().
ИМХО, так.
 
Верх