(?ix)
From\s*'([^']*)'\s*
(?:To\s*'([^']*)'\s*)?
(?:(NotIncluding)\s*)?
Regex для захвата символов с возможными повторами
Сразу извиняюсь, если поместил вопрос не в тот раздел.
Имеется текст, например
Код:
From '/*' To '*/' NotIncluding {
background: #e0e0e0;
}
background: #e0e0e0;
}
Код:
- /*
- */
- NotIncluding
Но :(
- Если не указать To '*/', то второе совпадение все-равно обнаруживается, хоть оно и пустое. Где недочет?
- И главное. Эта регулярка не приемлет апострофы ('), то есть этот текстКод:From '''' NotIncluding {
background: #e0e0e0;
}
Если не сложно - подскажите пожалуйста, где мои ошибки?
В приницпе, мне нужно, чтобы выражение "выбирало" символы внутри апострофов примерно по правилу
Код:
(?ixs)
( [^'] | (?<=')' )
( [^'] | (?<=')' )
Код:
#include <Array.au3>
Local Const $space = ' '
Local Const $spaces[4] = [@CR, @LF, @TAB, $space]
Func FalseSelector($sel)
Return IsBool($sel) And $sel = False
EndFunc
Func Screen($sq, $chr)
Return StringReplace($sq, $chr, $chr & $chr)
EndFunc
Func SkipSpaces($s)
Local $i = 1
While _ArraySearch($spaces, StringMid($s, $i, 1)) <> -1
$i += 1
WEnd
Return StringRight($s, StringLen($s) - $i + 1)
EndFunc
Func Detect($what, $s)
Local $len = StringLen($what)
For $i = 1 To $len
If StringMid($what, $i, 1) <> StringMid($s, $i, 1) Then
Return False
EndIf
Next
Return StringRight($s, StringLen($s) - $len)
EndFunc
Func SequenceUntilChar($chr, $sel)
Local $i = 1
Local $seq = ''
Local $brk = False
Local $len = StringLen($sel)
Do
$c = StringMid($sel, $i, 1)
If $c <> $chr Then
$seq &= $c
$i += 1
ElseIf StringMid($sel, $i + 1, 1) = $chr Then
$seq &= $chr
$i += 2
Else
$brk = True
EndIf
Until $brk Or $i >= $len
Return $seq
EndFunc
Func SkipFrom($sel, $sqfrom, $chr)
$sel = SkipSpaces($sel)
$sel = Detect('from', $sel)
$sel = SkipSpaces($sel)
$sel = Detect($chr & Screen($sqfrom, $chr) & $chr, $sel)
$sel = SkipSpaces($sel)
Return $sel
EndFunc
Func SkipTo($sel, $sqto, $chr)
Local $sl = $sel
$sel = Detect('to', $sel)
$sel = SkipSpaces($sel)
$sel = Detect($chr & Screen($sqto, $chr) & $chr, $sel)
If Not FalseSelector($sel) Then
$sel = SkipSpaces($sel)
Else
$sel = $sl
EndIf
Return $sel
EndFunc
Func SequenceFrom($sel, $chr)
$sel = SkipSpaces($sel)
$sel = Detect('from', $sel)
Local $seq = False
If Not FalseSelector($sel) Then
$sel = SkipSpaces($sel)
$sel = Detect($chr, $sel)
If Not FalseSelector($sel) Then
$seq = SequenceUntilChar($chr, $sel)
EndIf
EndIf
Return $seq
EndFunc
Func SequenceTo($sel, $chr, $sqfrom)
$sel = SkipFrom($sel, $sqfrom, $chr)
$sel = Detect('to', $sel)
Local $seq = False
If Not FalseSelector($sel) Then
$sel = SkipSpaces($sel)
$sel = Detect($chr, $sel)
If Not FalseSelector($sel) Then
$seq = SequenceUntilChar($chr, $sel)
EndIf
EndIf
Return $seq
EndFunc
Func NotIncluding($sel, $sqfrom, $sqto, $chr)
$sel = SkipFrom($sel, $sqfrom, $chr)
$sel = SkipTo($sel, $sqto, $chr)
$sel = Detect('NotIncluding', $sel)
If Not FalseSelector($sel) Then
$sel = True
EndIf
Return $sel
EndFunc
Func ParseSynhiSelector($sel, $chr)
Local $sqfrom = SequenceFrom($sel, $chr)
Local $sqto = SequenceTo($sel, $chr, $sqfrom)
Local $notincl = NotIncluding($sel, $sqfrom, $sqto, $chr)
Local $elems[3] = [$sqfrom, $sqto, $notincl]
Return $elems
EndFunc
Local Const $space = ' '
Local Const $spaces[4] = [@CR, @LF, @TAB, $space]
Func FalseSelector($sel)
Return IsBool($sel) And $sel = False
EndFunc
Func Screen($sq, $chr)
Return StringReplace($sq, $chr, $chr & $chr)
EndFunc
Func SkipSpaces($s)
Local $i = 1
While _ArraySearch($spaces, StringMid($s, $i, 1)) <> -1
$i += 1
WEnd
Return StringRight($s, StringLen($s) - $i + 1)
EndFunc
Func Detect($what, $s)
Local $len = StringLen($what)
For $i = 1 To $len
If StringMid($what, $i, 1) <> StringMid($s, $i, 1) Then
Return False
EndIf
Next
Return StringRight($s, StringLen($s) - $len)
EndFunc
Func SequenceUntilChar($chr, $sel)
Local $i = 1
Local $seq = ''
Local $brk = False
Local $len = StringLen($sel)
Do
$c = StringMid($sel, $i, 1)
If $c <> $chr Then
$seq &= $c
$i += 1
ElseIf StringMid($sel, $i + 1, 1) = $chr Then
$seq &= $chr
$i += 2
Else
$brk = True
EndIf
Until $brk Or $i >= $len
Return $seq
EndFunc
Func SkipFrom($sel, $sqfrom, $chr)
$sel = SkipSpaces($sel)
$sel = Detect('from', $sel)
$sel = SkipSpaces($sel)
$sel = Detect($chr & Screen($sqfrom, $chr) & $chr, $sel)
$sel = SkipSpaces($sel)
Return $sel
EndFunc
Func SkipTo($sel, $sqto, $chr)
Local $sl = $sel
$sel = Detect('to', $sel)
$sel = SkipSpaces($sel)
$sel = Detect($chr & Screen($sqto, $chr) & $chr, $sel)
If Not FalseSelector($sel) Then
$sel = SkipSpaces($sel)
Else
$sel = $sl
EndIf
Return $sel
EndFunc
Func SequenceFrom($sel, $chr)
$sel = SkipSpaces($sel)
$sel = Detect('from', $sel)
Local $seq = False
If Not FalseSelector($sel) Then
$sel = SkipSpaces($sel)
$sel = Detect($chr, $sel)
If Not FalseSelector($sel) Then
$seq = SequenceUntilChar($chr, $sel)
EndIf
EndIf
Return $seq
EndFunc
Func SequenceTo($sel, $chr, $sqfrom)
$sel = SkipFrom($sel, $sqfrom, $chr)
$sel = Detect('to', $sel)
Local $seq = False
If Not FalseSelector($sel) Then
$sel = SkipSpaces($sel)
$sel = Detect($chr, $sel)
If Not FalseSelector($sel) Then
$seq = SequenceUntilChar($chr, $sel)
EndIf
EndIf
Return $seq
EndFunc
Func NotIncluding($sel, $sqfrom, $sqto, $chr)
$sel = SkipFrom($sel, $sqfrom, $chr)
$sel = SkipTo($sel, $sqto, $chr)
$sel = Detect('NotIncluding', $sel)
If Not FalseSelector($sel) Then
$sel = True
EndIf
Return $sel
EndFunc
Func ParseSynhiSelector($sel, $chr)
Local $sqfrom = SequenceFrom($sel, $chr)
Local $sqto = SequenceTo($sel, $chr, $sqfrom)
Local $notincl = NotIncluding($sel, $sqfrom, $sqto, $chr)
Local $elems[3] = [$sqfrom, $sqto, $notincl]
Return $elems
EndFunc
Код:
Func TestParseSynhiSelector()
Local $chr = "'"
Local $sqfrom = '/*'
Local $sqto = '*/'
; 111: All parts
Local $sel = _
'From ' & $chr & $sqfrom & $chr & _
' To ' & $chr & $sqto & $chr & _
' NotIncluding '
Local $actual = ParseSynhiSelector($sel, $chr)
Local $expected[3] = [$sqfrom, $sqto, True]
If Not ArraysEquals($expected, $actual) Then
MsgBox(16, 'Test failed', 'Error is found in ParseSynhiSelector() function.')
Return False
EndIf
; 110: Without NotIncluding, apostrophes
$sqfrom = "'"
$sqto = "'"
$sel = _
'From ' & $chr & ($sqfrom & $sqfrom) & $chr & _
' To ' & $chr & ($sqto & $sqto) & $chr
Local $actual = ParseSynhiSelector($sel, $chr)
$expected[0] = $sqfrom
$expected[1] = $sqto
$expected[2] = False
If Not ArraysEquals($expected, $actual) Then
MsgBox(16, 'Test failed', 'Error is found in ParseSynhiSelector() function.')
Return False
EndIf
; 100: Only From part
$sqfrom = "REM"
$sel = _
'From ' & $chr & $sqfrom & $chr
Local $actual = ParseSynhiSelector($sel, $chr)
$expected[0] = $sqfrom
$expected[1] = ''
If Not ArraysEquals($expected, $actual) Then
MsgBox(16, 'Test failed', 'Error is found in ParseSynhiSelector() function.')
Return False
EndIf
; 101: Without To part
Local $sel = _
'From ' & $chr & $sqfrom & $chr & _
' NotIncluding '
Local $actual = ParseSynhiSelector($sel, $chr)
$expected[2] = True
If Not ArraysEquals($expected, $actual) Then
MsgBox(16, 'Test failed', 'Error is found in ParseSynhiSelector() function.')
Return False
EndIf
Return True
EndFunc
Local $chr = "'"
Local $sqfrom = '/*'
Local $sqto = '*/'
; 111: All parts
Local $sel = _
'From ' & $chr & $sqfrom & $chr & _
' To ' & $chr & $sqto & $chr & _
' NotIncluding '
Local $actual = ParseSynhiSelector($sel, $chr)
Local $expected[3] = [$sqfrom, $sqto, True]
If Not ArraysEquals($expected, $actual) Then
MsgBox(16, 'Test failed', 'Error is found in ParseSynhiSelector() function.')
Return False
EndIf
; 110: Without NotIncluding, apostrophes
$sqfrom = "'"
$sqto = "'"
$sel = _
'From ' & $chr & ($sqfrom & $sqfrom) & $chr & _
' To ' & $chr & ($sqto & $sqto) & $chr
Local $actual = ParseSynhiSelector($sel, $chr)
$expected[0] = $sqfrom
$expected[1] = $sqto
$expected[2] = False
If Not ArraysEquals($expected, $actual) Then
MsgBox(16, 'Test failed', 'Error is found in ParseSynhiSelector() function.')
Return False
EndIf
; 100: Only From part
$sqfrom = "REM"
$sel = _
'From ' & $chr & $sqfrom & $chr
Local $actual = ParseSynhiSelector($sel, $chr)
$expected[0] = $sqfrom
$expected[1] = ''
If Not ArraysEquals($expected, $actual) Then
MsgBox(16, 'Test failed', 'Error is found in ParseSynhiSelector() function.')
Return False
EndIf
; 101: Without To part
Local $sel = _
'From ' & $chr & $sqfrom & $chr & _
' NotIncluding '
Local $actual = ParseSynhiSelector($sel, $chr)
$expected[2] = True
If Not ArraysEquals($expected, $actual) Then
MsgBox(16, 'Test failed', 'Error is found in ParseSynhiSelector() function.')
Return False
EndIf
Return True
EndFunc
Код:
ParseSynhiSelector($sel, $chr)
Возвращает массив. Элемент с индексом 0 -- это строка "/*" (в примере, приведенном в вопросе), 1 -- "*/", а 2 -- булевское значение, указывающее на наличие строки "NotIncluding" в селекторе.