Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   AutoIt (http://forum.oszone.net/forumdisplay.php?f=103)
-   -   [решено] Поиск повторяющихся слов в тексте при помощи StringRegExp (http://forum.oszone.net/showthread.php?t=278388)

support23 26-02-2014 12:53 2315970

Поиск повторяющихся слов в тексте при помощи StringRegExp
 
Привет всем!
Возможно ли используя функцию StringRegExp определить наиболее часто повторяющееся слово в тексте?

Пример текста:
18.02.2014 15:58:13 user1
18.02.2014 17:30:58 user2
19.02.2014 12:54:34 user2
19.02.2014 13:14:28 user5
20.02.2014 14:59:43 user2
20.02.2014 16:31:05 user4
21.02.2014 11:47:27 user2
23.02.2014 12:21:25 user2
23.02.2014 10:35:14 user3
24.02.2014 13:50:20 user2

Слово для поиска - userX может содержать латинские буквы, цифры, символы "_" и "-"

Если через StringRegExp этого сделать нельзя, какой еще метод можно использовать?

p.s. желательно с примерами.
Заранее спасибо!

Iska 26-02-2014 13:08 2315975

Проще всего — представлять текстовый файл как базу данных. Тогда можно, использовав, например, OLEDB с запросом вида «SELECT COUNT(Field3) AS TotalField3 GROUP Field3 ORDER BY TotalField3 DESC», определить наиболее часто встречающееся из «UserXX».

Iska 26-02-2014 22:22 2316307

Как-то не дочитал:
Цитата:

Цитата support23
p.s. желательно с примерами. »

читать дальше »
Код:

AutoItSetOption("MustDeclareVars", 1)

Local Const $adOpenStatic = 3
Local Const $adLockOptimistic = 3
Local Const $adCmdText = 1

Local $sPathToSchema = "E:\Песочница\0365"
Local $sSourceFile  = "0001.txt"

Local $oRecordSet = ObjCreate("ADODB.Recordset")

If Not FileExists($sPathToSchema & "\") Then
        ConsoleWrite("Folder [" & $sPathToSchema & "] not found." & @CRLF)
        Exit(1)
EndIf

If Not FileExists($sPathToSchema & "\" & $sSourceFile) Then
        ConsoleWrite("Source file [" & $sSourceFile & "] not found." & @CRLF)
        Exit(2)
EndIf

CreateSchema($sPathToSchema & "\Schema.ini", $sSourceFile)

$oRecordSet.Open( _
                "SELECT TOP 1 [Name], COUNT(*) AS [Count] " & _
                "FROM [" & $sSourceFile & "] " & _
                "GROUP BY [Name] " & _
                "ORDER BY COUNT(*) DESC", _
                "Provider=Microsoft.Jet.OLEDB.4.0;Data Source='" & $sPathToSchema & "';Extended Properties=""text;""", _
                $adOpenStatic, $adLockOptimistic, $adCmdText _
        )

ConsoleWrite("Name:  " & $oRecordSet.Fields.Item("Name").Value & @CRLF)
ConsoleWrite("Count: " & $oRecordSet.Fields.Item("Count").Value & @CRLF)

$oRecordSet.Close
$oRecordSet = 0

RemoveSchema($sPathToSchema & "\Schema.ini")

Exit(0)
;=============================================================================

;=============================================================================
Func CreateSchema($sFullPathToSchemaIni, $sSourceFile)
        If FileExists($sFullPathToSchemaIni) Then
                FileDelete($sFullPathToSchemaIni)
        EndIf

        Local $hFile = FileOpen($sFullPathToSchemaIni, 2)

        FileWriteLine($hFile, "[" & $sSourceFile & "]")
        FileWriteLine($hFile, "ColNameHeader=False")
        FileWriteLine($hFile, "Format=Delimited( )")
        FileWriteLine($hFile, "TextDelimiter=none")
        FileWriteLine($hFile, "DateTimeFormat=dd.mm.yyyy")
        FileWriteLine($hFile, "CharacterSet=ANSI")
        FileWriteLine($hFile, "Col1=Date date")
        FileWriteLine($hFile, "Col2=Time char")
        FileWriteLine($hFile, "Col3=Name char")

        FileClose($hFile)

        FileSetAttrib($sFullPathToSchemaIni, "+H")
EndFunc
;=============================================================================

;=============================================================================
Func RemoveSchema($sFullPathToSchemaIni)
        If FileExists($sFullPathToSchemaIni) Then
                FileDelete($sFullPathToSchemaIni)
        EndIf
EndFunc
;=============================================================================


Результат:
читать дальше »
Цитата:

Код:

Name:  user2
Count: 6



P.S. Хорошо бы образец реального файла.

support23 27-02-2014 13:06 2316643

Вложений: 1
Файл во вложении

При выполнении кода, на тексте для примера, указанного в первом сообщении, все работает

При выполнении кода с данным файлом получаю ошибку:

The requested action with this object has failed.:
$oRecordSet.Open( "SELECT TOP 1 [Name], COUNT(*) AS [Count] " & "FROM [" & $sSourceFile & "] " & "GROUP BY [Name] " & "ORDER BY COUNT(*) DESC", "Provider=Microsoft.Jet.OLEDB.4.0;Data Source='" & $sPathToSchema & "';Extended Properties=""text;""", $adOpenStatic, $adLockOptimistic, $adCmdText )
$oRecordSet.Open( "SELECT TOP 1 [Name], COUNT(*) AS [Count] " & "FROM [" & $sSourceFile & "] " & "GROUP BY [Name] " & "ORDER BY COUNT(*) DESC", "Provider=Microsoft.Jet.OLEDB.4.0;Data Source='" & $sPathToSchema & "';Extended Properties=""text;""", $adOpenStatic, $adLockOptimistic, $adCmdText )^ ERROR

Iska 27-02-2014 15:43 2316773

support23, достаточно переименовать «auth_users.log» в «auth_users.txt».

support23 28-02-2014 08:04 2317086

Все отлично работает, благодарю за решение !

madmasles 28-02-2014 11:33 2317169

support23,
Мой вариант.
Код:

#include <Array.au3>

Local $sFile = @ScriptDir & '\auth_users.log', $aTmp, $iUb, $oDict, $iTmp, $aMax[2], $aRes[1], $aKey, $aItem

$aTmp = StringRegExp(FileRead($sFile), '(?<=:\d{2})\h{0,}([^\h]+?)[\n\r]', 3)
If @error Then Exit 13
$iUb = UBound($aTmp)

$oDict = ObjCreate('Scripting.Dictionary')
For $i = 0 To $iUb - 1
    If $oDict.Exists($aTmp[$i]) Then
        $iTmp = $oDict.Item($aTmp[$i]) + 1
        $oDict.Item($aTmp[$i]) = $iTmp
        If $aMax[1] < $iTmp Then
            $aMax[1] = $iTmp
            $aMax[0] = $aTmp[$i]
        EndIf
    Else
        $oDict.Add($aTmp[$i], 1)
    EndIf
Next
ConsoleWrite('Max "' & $aMax[0] & '", count = ' & $aMax[1] & @LF)
;~ бонус:
$iUb = $oDict.Count
ReDim $aRes[$iUb + 1][2]
$aKey = $oDict.Keys
$aItem = $oDict.Items
$aRes[0][0] = $aMax[0]
$aRes[0][1] = $aMax[1]
For $i = 0 To $iUb - 1
    $aRes[$i + 1][0] = $aKey[$i]
    $aRes[$i + 1][1] = $aItem[$i]
Next
$oDict = 0
$aTmp = 0
$aMax = 0
_ArrayDisplay($aRes)
;~ в [0][0] массива:    слово, всречающееся максимальное число раз
;~ в [0][1] массива:    кол-во его вхождений
;~ в [1-n][0] массива:    уникальные имена
;~ в [1-n][1] массива:    кол-во их вхождений


support23 28-02-2014 14:13 2317247

Спасибо, тоже отличное решение, особенно с учетом бонуса)

Iska 28-02-2014 16:04 2317305

support23, если нужен такой же «бонус» в приведённом мною коде, замените:
Код:

$oRecordSet.Open( _
                "SELECT TOP 1 [Name], COUNT(*) AS [Count] " & _
                "FROM [" & $sSourceFile & "] " & _
                "GROUP BY [Name] " & _
                "ORDER BY COUNT(*) DESC", _
                "Provider=Microsoft.Jet.OLEDB.4.0;Data Source='" & $sPathToSchema & "';Extended Properties=""text;""", _
                $adOpenStatic, $adLockOptimistic, $adCmdText _
        )

ConsoleWrite("Name:  " & $oRecordSet.Fields.Item("Name").Value & @CRLF)
ConsoleWrite("Count: " & $oRecordSet.Fields.Item("Count").Value & @CRLF)

на:
Код:

$oRecordSet.Open( _
                "SELECT [Name], COUNT(*) AS [Count] " & _
                "FROM [" & $sSourceFile & "] " & _
                "GROUP BY [Name] " & _
                "ORDER BY COUNT(*) DESC", _
                "Provider=Microsoft.Jet.OLEDB.4.0;Data Source='" & $sPathToSchema & "';Extended Properties=""text;""", _
                $adOpenStatic, $adLockOptimistic, $adCmdText _
        )

While Not $oRecordSet.EOF
        ConsoleWrite("Count: " & $oRecordSet.Fields.Item("Count").Value & @TAB & "Name:  " & $oRecordSet.Fields.Item("Name").Value & @CRLF)

        $oRecordSet.MoveNext()
WEnd


support23 28-02-2014 17:28 2317358

Цитата:

Цитата Iska
support23, если нужен такой же «бонус» в приведённом мною коде, замените: »

Большое спасибо!

В обоих случаях получил функционал больше чем запрашивал изначально, Iska и madmasles вы очень помогли!

AZJIO 02-03-2014 01:46 2317917

support23, посмотри мою Compare strings. Там есть в комбо - "Подсчёт уникальных строк", а в исходниках есть функция. Естественно даты нужно обрезать. Если используя рег.выр., то упрощённо обрезать указанное количество символов в начале каждой строки. Если нет так часто приходится делать, то в Notepad++ можно обрезать выделив столбиком, а оставшийся список обработать в "Compare strings".


Время: 20:34.

Время: 20:34.
© OSzone.net 2001-