* * *    
Главная » Статьи » Код PB

Просмотров: 5155 | Дата: 21.11.2024 | Коментарии (0)

Регулярные выражения



Регулярные выражения (англ. RegularExpression) — это формальный язык поиска и осуществления манипуляций с подстроками в тексте, основанный на использовании мета символов
По сути это строка-образец (англ. pattern, по-русски её часто называют «шаблоном», «маской»), состоящая из символов и мета символов и задающая правило поиска
Вся суть применения регулярных выражений практически сводится к правильному построению шаблона для поиска.
А сам код поиска остаётся в принципе неизменен:

String.s = "строка в которой производится поиск"
Find.s ="шаблон поиска"
 
CreateRegularExpression(0,Find,#PB_RegularExpression_DotAll)
 Dim Matched.s(10)
 Matching.i = ExtractRegularExpression(0,String,Matched())
 For i = 0 To (Matching - 1)
 Debug Matched(i) ;результат
 Next 
FreeRegularExpression(0)
;


Например из строки текста нужно получить все конструкции заключенные в одинарные кавычки:

 

String.s = "Искомое слово начинаться например с 'динарные кавычки' Средний строка может 'быть' что угодно"
 
 ;(') ;Искомое слово начинаться например с ' 
 ;\S ;Не пробел
 ;(.*?) ;Средний строка может быть что угодно.
 ;(') ;Искомое слово должна заканчиваться например на ' 

 Find.s ="(')\S(.*?)(')"
 
CreateRegularExpression(0,Find,#PB_RegularExpression_DotAll)
 Dim Matched.s(10)
 Matching.i = ExtractRegularExpression(0,String,Matched())
 For i = 0 To (Matching - 1)
 Debug Matched(i)
 Next 
FreeRegularExpression(0)
;


Интересен вариант, когда нужно исключит из найденных слов, шаблоны начала и конца поиска, в верхнем варианте это одинарные кавычки, или может быть любая другая конструкцию.
Можно воспользоваться функцией RemoveString(), а можно применить другой шаблон для поиска:

 

String.s = "Искомое слово начинаться например с 'динарные кавычки' Средний строка может 'быть' что угодно"
 
 ;(?<=()') ;Искомое слово начинаться например с ' конструкция (?<=()') убирает '
 ;\S ;Не пробел
 ;(.*?) ;Средний строка может быть что угодно.
 ;(?=()') ;Искомое слово должна заканчиваться например на ' конструкция (?=()') убирает '

 Find.s ="(?<=()')\S(.*?)(?=()')"
 

CreateRegularExpression(0,Find,#PB_RegularExpression_DotAll)
 Dim Matched.s(10)
 Matching.i = ExtractRegularExpression(0,String,Matched())
 For i = 0 To (Matching - 1)
 Debug Matched(i)
 Next 
FreeRegularExpression(0)
;


Пример нахождения IP адреса:

String.s = "IP:92.113.63.76 нужно выделить из текста все IP адреса http://127.0.0.1/ " 
 
Find.s ="([0-9][0-9][0-9]|[0-9][0-9]|[0-9]).([0-9][0-9][0-9]|[0-9][0-9]|[0-9]).([0-9][0-9][0-9]|[0-9][0-9]|[0-9]).([0-9][0-9][0-9]|[0-9][0-9]|[0-9])"
 
CreateRegularExpression(0,Find,#PB_RegularExpression_DotAll)
 Dim Matched.s(10)
 Matching.i = ExtractRegularExpression(0,String,Matched())
 For i = 0 To (Matching - 1)
 Debug Matched(i)
 Next 
FreeRegularExpression(0)
;



Подробно о построении шаблонов поиска написано на страницах:


http://www.softring.ru/articles/perlregexp1.html
http://www.softring.ru/articles/perlregexp2.html
http://www.softring.ru/articles/perlregexp3.html

Синтаксис регулярных выражений

Таблица: Мета символы в регулярных выражениях

СимволОписание
\Для символов, которые обычно трактуются буквально, означает, что следующий символ является метасимволом. Например, /n/ соответствует букве n, а /\n/ соответствует символу перевода строки. Для метасимволов означает, что символ должен пониматься буквально. Например, /^/ означает начало строки, а /\^/ соответствует просто символу ^. /\\/ соответствует обратной косой черте \.
^Соответствует началу строки (ср. модификатор m).
$Соответствует концу строки (ср. модификатор m).
.Соответствует любому символу, кроме разрыва строки (ср. модификатор s).
*Соответствует повторению предыдущего символа нуль или более раз.
+Соответствует повторению предыдущего символа один или более раз.
?Соответствует повторению предыдущего символа нуль или один раз.
(pattern)Соответствует строке pattern и запоминает найденное соответствие.
x|yСоответствует x или y.
{n}n — неотрицательное число. Соответствует ровно n вхождениям предыдущего символа.
{n,}n — неотрицательное число. Соответствует n или более вхождениям предыдущего символа. /x{1,}/ эквивалентно /x+/. /x{0,}/ эквивалентно /x*/.
{n,m}n и m — неотрицательные числа. Соответствует не менее чем n и не более чем m вхождениям предыдущего символа. /x{0,1}/ эквивалентно /x?/.
[xyz]Соответствует любому символу из заключенных в квадратные скобки.
[^xyz]Соответствует любому символу, кроме заключенных в квадратные скобки.
[a-z]Соответствует любому символу в указанном диапазоне.
[^a-z]Соответствует любому символу, кроме лежащих в указанном диапазоне.
\aСоответствует символу звонок (BEL).
\AСоответствует только началу строки, даже с модификатором m.
\bСоответствует границе слова, т. е. позиции между \w и \W в любом порядке.
\BСоответствует любой позиции, кроме границы слова.
\сXСоответствует символу Ctrl+X. Например, /\cI/ эквивалентно /\t/.
\CСоответствует одному байту, даже при директиве use utf8.
\dСоответствует цифре. Эквивалентно [0-9].
\DСоответствует нецифровому символу. Эквивалентно [^0-9].
\eСоответствует символу escape (ESC).
\EКонец преобразований \L, \Q, \U.
\fСоответствует символу перевода формата (FF).
\GСоответствует позиции в строке, равной pos().
\lПреобразует следующий символ в нижний регистр.
\LПреобразует символы в нижний регистр до \E.
\nСоответствует разрыву строк.
\ppropertyСоответствует символам Unicode, обладающим свойством property. Если property задается несколькими символами, используйте синтаксис \p{property}.
\PpropertyСоответствует символам Unicode, не обладающим свойством property. Если property задается несколькими символами, используйте синтаксис \P{property}.
\QДобавляет символ "\" перед метасимволами до \E.
\rСоответствует символу возврата каретки (CR).
\sСоответствует символу пробела. Эквивалентно /[ \f\n\r\t]/.
\SСоответствует любому непробельному символу. Эквивалентно /[^ \f\n\r\t]/.
\tСоответствует символу табуляции (HT).
\uПреобразует следующий символ в верхний регистр.
\UПреобразует символы в верхний регистр до \E.
\wСоответствует латинской букве, цифре или подчеркиванию. Эквивалентно /[A-Za-z0-9_] /.
\WСоответствует любому символу, кроме латинской буквы, цифры или подчеркивания. Эквивалентно /[^A-Za-z0-9_] /.
\XСоответствует последовательности символов Unicode из основного символа и набора диакритических значков. Эквивалентно выражению /C<(?:\PM\pM*)>/.
\zСоответствует только концу строки, даже с модификатором m.
\ZСоответствует только концу строки или разрыву строк в конце строки, даже с модификатором m.
\nn — положительное число. Соответствует n-ной запомненной подстроке. Если левых скобок до этого символа меньше, чем n, и n > 9, то эквивалентно \0n.
\0nn — восьмеричное число, не большее 377. Соответствует символу с восьмеричным кодом n. Например, /\011/ эквивалентно /\t/.
\xnn — шестнадцатеричное число, состоящее из двух цифр. Соответствует символу с шестнадцатеричным кодом n. Например, /\x31/ эквивалентно /1/.
\x{n}n — шестнадцатеричное число, состоящее из четырех цифр. Соответствует символу Unicode с шестнадцатеричным кодом n. Например, /\x{2663}/ эквивалентно /♣/.
  

Расширенные образцы

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

(?#text)
Комментарий. Вся конструкция игнорируется.

(?modifiers-modifiers)
Включает или выключает заданные модификаторы. Модификаторы, стоящие до символа -, включаются, стоящие после него — выключаются.
Пример:
if (/aaa/) { … } # сопоставление с учетом регистра
if (/(?i)aaa/) { … } # сопоставление без учета регистра

(?:pattern)
(?modifiers-modifiers:pattern)
Позволяет группировать подвыражения регулярного выражения без запоминания найденного соответствия. Вторая форма дополнительно включает или выключает заданные модификаторы. Например, выражение /ко(?:т|шка)/ — это краткая запись выражения /кот|кошка/.

(?=pattern)
Соответствие с заглядыванием вперед без запоминания найденного соответствия. Например, выражение /Windows (?=95|98|NT|2000)/ соответствует "Windows" в строке "Windows 98", но не соответствует в строке "Windows 3.1". После сопоставления поиск продолжается с позиции, следующей за найденным соответствием, без учета заглядывания вперед.

(?!pattern)
Несоответствие с заглядыванием вперед без запоминания найденного соответствия. Например, выражение /Windows (?!95|98|NT|2000)/ соответствует "Windows" в строке "Windows 3.1", но не соответствует в строке "Windows 98". После сопоставления поиск продолжается с позиции, следующей за найденным соответствием, без учета заглядывания вперед.

(?<=pattern)
Соответствие с заглядыванием назад без запоминания найденного соответствия. Например, выражение /(?<=\t)\w+/ соответствует слову, следующему за символом табуляции, и символ табуляции не включается в $&. Фрагмент, соответствующий заглядыванию назад, должен иметь фиксированную ширину.

(?<!pattern)
Несоответствие с заглядыванием назад без запоминания найденного соответствия. Например, выражение /(?<!\t)\w+/ соответствует слову, перед которым нет символа табуляции. Фрагмент, соответствующий заглядыванию назад, должен иметь фиксированную ширину.



К примеру, код сканирующий ваши жесткие диски (в коде нужно правильно указать название дисков), находит файлы с расширением PureBasic pb и pbi, производит в них поиск по шаблону:

"(?<![\.\w])[a-zA-Z_]\w*(?=(?:\.\w+\s*|\s*)\()"

и составляет список TOP-20 самых популярных функций.
Поиск происходит долго, нужно терпение...

Enumeration
#RegularExpression
EndEnumeration

CreateRegularExpression(#RegularExpression, "(?<![\.\w])[a-zA-Z_]\w*(?=(?:\.\w+\s*|\s*)\()")

Structure Befehl
Name$
Count.i
EndStructure

Global NewMap Befehl.i()
Global NewList Befehl2.Befehl()

Procedure FindAlFiles(DirectoryName$)
Debug ">> "+DirectoryName$
Protected File, Count, i
Protected Dim Result$(0)
Protected Directory = ExamineDirectory(#PB_Any, DirectoryName$, "*")
If Directory
 While NextDirectoryEntry(Directory)
 Select DirectoryEntryType(Directory)
 Case #PB_DirectoryEntry_Directory
 If DirectoryEntryName(Directory) <> "." And DirectoryEntryName(Directory) <> ".."
 FindAlFiles(DirectoryName$+"\"+DirectoryEntryName(Directory))
 EndIf
 Case #PB_DirectoryEntry_File
 If Left(GetExtensionPart(DirectoryEntryName(Directory)),2)="pb"
 File = ReadFile(#PB_Any, DirectoryName$+"\"+DirectoryEntryName(Directory)) 
 If File
 Repeat
 String$ = ReadString(File)
 Count = ExtractRegularExpression(#RegularExpression, String$, Result$())
 For i = 0 To Count-1
 Befehl(Result$(i)) + 1
 Next
 Until Eof(File)
 CloseFile(File)
 EndIf
 EndIf 
 EndSelect
 Wend
EndIf
EndProcedure

;FindAlFiles("D:\")
FindAlFiles("C:\")
FindAlFiles("F:\")

ForEach Befehl()
 AddElement(Befehl2())
 Befehl2()\Name$ = MapKey(Befehl())
 Befehl2()\Count = Befehl()
Next

SortStructuredList(Befehl2(), #PB_Sort_Descending, OffsetOf(Befehl\Count), #PB_Sort_Integer)

Top10 = 1
ForEach Befehl2() 
 Debug Str(Top10)+". "+Befehl2()\Name$+" [ "+Str(Befehl2()\Count)+" ]"
 Top10 + 1
 If Top10 = 21 : Break : EndIf
Next
;


Моя двадцатка:

1. sgx [ 8846 ]
2. RGB [ 8567 ]
3. Chr [ 7381 ]
4. Str [ 6967 ]
5. sgx_keyLay [ 5232 ]
6. MessageRequester [ 4265 ]
7. WindowID [ 3870 ]
8. ImageID [ 3682 ]
9. AddGadgetItem [ 3675 ]
10. SetGadgetText [ 3101 ]
11. OpenWindow [ 3069 ]
12. SetGadgetState [ 3032 ]
13. Box [ 2941 ]
14. Random [ 2896 ]
15. ButtonGadget [ 2651 ]
16. v4 [ 2569 ]
17. StartDrawing [ 2538 ]
18. StopDrawing [ 2537 ]
19. Len [ 2487 ]
20. CallFunction [ 2385 ]












Сайт посвящён языку программирования PureBasic — коммерческий компилятор языка программирования, использующего синтаксис BASIC. Предназначен для создания кроссплатформенных приложений для AmigaOS, Linux, Microsoft Windows, Windows NT и Mac OS X. Разработан компанией Fantaisie Software.