Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Regex для захвата символов с возможными повторами

53K
26 декабря 2012 года
transParent
18 / / 12.08.2012
Добрый вечер, народ.
Сразу извиняюсь, если поместил вопрос не в тот раздел.

Имеется текст, например

 
Код:
From '/*' To '*/' NotIncluding {
    background: #e0e0e0;
}
Есть регулярка

 
Код:
(?ix)
From\s*'([^']*)'\s*
(?:To\s*'([^']*)'\s*)?
(?:(NotIncluding)\s*)?
Работает верно: в большинстве случаев возвращает то, что нужно:
  • /*
  • */
  • NotIncluding

Но :(
  1. Если не указать To '*/', то второе совпадение все-равно обнаруживается, хоть оно и пустое. Где недочет?
  2. И главное. Эта регулярка не приемлет апострофы ('), то есть этот текст

     
    Код:
    From '''' NotIncluding {
         background: #e0e0e0;
    }
    ей не обрабатывается. А хотелось бы :)

Если не сложно - подскажите пожалуйста, где мои ошибки?

В приницпе, мне нужно, чтобы выражение "выбирало" символы внутри апострофов примерно по правилу

 
Код:
(?ixs)
(  [^']  |  (?<=')'  )
Заранее благодарен за любую помощь!
53K
31 декабря 2012 года
transParent
18 / / 12.08.2012
Решил свою проблему. Без использования регексов. К сожалению.

Код:
#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
Вот пример использования:
Код:
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
Созданная функция
 
Код:
ParseSynhiSelector($sel, $chr)
в качестве параметра $sel принимает селектор, описанный в вопросе, $chr -- это символ-ограничитель (в вопросе -- апостроф).
Возвращает массив. Элемент с индексом 0 -- это строка "/*" (в примере, приведенном в вопросе), 1 -- "*/", а 2 -- булевское значение, указывающее на наличие строки "NotIncluding" в селекторе.

Знаете кого-то, кто может ответить? Поделитесь с ним ссылкой.

Ваш ответ

Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог