Что нового

[RegExp] Поиск повторяющихся слов в тексте используя обратные ссылки

SET777

Новичок
Сообщения
51
Репутация
3
Доброго времени всем!
Есть некий текст в котором нужно найти повторяющиеся слова и цифры используя именно обратные ссылки в шаблоне. Вот не рабочий пример с двумя обратными ссылками:
Код:
$sText = 'too too 66 66'
$sPattern =  '([a-z]+) +([0-9]+) +\1\2'
$aResult = StringRegExp($sText, $sPattern, 2)
For $i = 0 To UBound($aResult) - 1
    ConsoleWrite($aResult[$i] & @CRLF) Next

с одной ссылкой все прекрасно отрабатывает.
Код:
$sPattern =  '([a-z]+) +\1'

Со ссылками "$1 $2" в шаблоне замены разобрался (в уроках по регэкспам Redline очень доходчиво все расписал), а вот несколько ссылок на найденные группы в самом шаблоне никак не поддаются( Поиском пользовался, ничего что помогло бы решить проблему не нашел. :(
 

asdf8

Скриптер
Сообщения
564
Репутация
152
Поробуй так:
Код:
#Include <Array.au3>
$sText = 'too too 66 66'
$sPattern = '([a-z0-9]+) +\1'
$aResult = StringRegExp($sText, $sPattern, 3)
_ArrayDisplay($aResult)
 
Автор
S

SET777

Новичок
Сообщения
51
Репутация
3
asdf8 Так то оно да, работает, спасибо за вариант, :ok: но как все таки пользоваться несколькими обратными ссылками на найденные группы в шаблоне?
 

asdf8

Скриптер
Сообщения
564
Репутация
152
SET777 [?]
как все таки пользоваться несколькими обратными ссылками на найденную группу в шаблоне?

В каком месте здесь нужны несколько обратных ссылок?
Чтобы получить нужный ответ, нужно правильно формулировать вопрос.
 

gregaz

AutoIT Гуру
Сообщения
1,166
Репутация
299
Так наверное будет корректнее :
Код:
#Include<Array.au3>
$sText= "11 too 66 too 55 too 66 55 55 77"

$sPattern = "(\w+?)\s+(\S*\s)*?\1"

$aRezult = StringRegExp( $sText, $sPattern,3 )

_ArrayDisplay($aRezult, ' Test Rezult ')

послольку для такого текста предыдущий вариант не корректен

Хотя оказывается и мой не совсем корректен
 
Автор
S

SET777

Новичок
Сообщения
51
Репутация
3
asdf8 В шаблоне
Код:
$sPattern =  '([a-z]+) +([0-9]+) +\1\2'
метасимвол \1 ссылается на ([a-z]+), а метасимвол \2 ссылается на ([0-9]+) и.т.д. Как это правильно написать?
 

asdf8

Скриптер
Сообщения
564
Репутация
152
SET777 [?]
метасимвол \1 ссылается на ([a-z]+), а метасимвол \2 ссылается на ([0-9]+) и.т.д. Как это правильно написать?

Для примера из первого поста, в общем случае - никак.
Либо за несколько раз:
Код:
$sPattern = '([0-9]+) +\1'
$sPattern = '([a-z]+) +\1'


и, потом, сложить два массива.

Или за один раз

Код:
$sPattern = '([a-z0-9]+) +\1'


но итоговый результат получится одинаковый.

Нужно определиться - что должен делать скрипт, после этого - какие данные должны появиться на выходе регэкспов и как их далее обрабатывать. По моему пример из первого поста не очень удачный.

Только для примера из первого поста:

Код:
#Include <Array.au3>
$sText = 'too too 66 66'
$sPattern = '([a-z]+) +\1 +([0-9]+) +\2'
$aResult = StringRegExp($sText, $sPattern, 3)
_ArrayDisplay($aResult)
 

Redline

AutoIT Гуру
Сообщения
506
Репутация
375
Код:
$sText = 'too too 66 66 tro tru'
$sPattern =  '([a-z]+|[0-9]+)\s*?\1'
$aResult = StringRegExp($sText, $sPattern, 3)
For $i = 0 To UBound($aResult) - 1
    ConsoleWrite($aResult[$i] & @CRLF)
Next
 
Автор
S

SET777

Новичок
Сообщения
51
Репутация
3
asdf8
Пример из первого поста - прототип выражения из книги "Дж. Фридла - Регулярные выражения" там, на 42 странице написано: "Конечно в выражение можно включить несколько пар круглых скобок и ссылаться на совпавший текст при помощи метасимволов \1, \2, \3 и.т.д. Пары скобок нумеруются в соответствии с порядковым номером открывающей скобки слева направо..." Заглянул в справку по Autoit что бы найти похожее, в описании функции StringRegExp в разделе "Метасимволы подстановки" первым идет описание: "\1 - \9 - ссылка на найденную группу в самом шаблоне и в шаблоне замены". Так значит выходит, что интервал обратных ссылок \1 - \9 в справке применим только для шаблонов замены, но не для использования его в самих шаблонах регулярных выражений кроме как в последнем вашем примере и в первом (ссылаться на совпавший текст в скобках при помощи только одного метасимвола - \1 и не больше)? Он ведь (последний пример) ищет не все совпадения в тексте в отличии от вашего первого поста.

Конструкция выбора Redline в круглых скобках то что нужно, т.е. несколько метасимволов - \1, \2, \3 в данном случае никак не применимы и не поддерживаются?
 

asdf8

Скриптер
Сообщения
564
Репутация
152
SET777 [?]
т.е. метасимволы \1, \2, \3 в данном случае никак не применимы и не поддерживаются?

Все поддерживается, а применимость зависит от поставленной задачи - результат у всех рабочих примеров в этой ветке одинаковый.
 

Redline

AutoIT Гуру
Сообщения
506
Репутация
375
Вариант лучше чуть получше:
Код:
$sText = 'too too 66 66 tro tru 25 try 96 96 tre rtyrty 45 45ert er er '
$sPattern =  '((?:[a-z]+|[0-9]+)\s+)\1'
$aResult = StringRegExp($sText, $sPattern, 3)
For $i = 0 To UBound($aResult) - 1
    ConsoleWrite($aResult[$i] & @CRLF)
Next

Иначе "съедало", сочетания внутри слов (типа "тритри"), но теперь в конце строки необходимо ставить пробел!

PS: поиск правильного шаблона - это целая задача, и она может иметь несколько решений, при том все будут правильными, но какие-то более рациональными, другие более компактными. Поэтому не стоит искать решение в одном направлении - надо крутиться и улучшать найденные решения (как в этом случае)
 
Автор
S

SET777

Новичок
Сообщения
51
Репутация
3
Теперь разобрался, всем спасибо! :smile:
 
Верх