Совпадение до x регулярное выражение или y регулярное выражение - PullRequest
5 голосов
/ 30 января 2011

У меня сейчас есть это:

^(.+)\(\w+\)|^(.+)\s\(\d{3}\:\d{3}\s\-\s\d{3}\:\d{3}\)

# 1, которому он соответствует только Foo's
# 2 Foo имеет , что является правильным
#3 соответствует foo , но находится в третьем элементе массива [2]:

3rd array output:
    (
        [0] => Foo (100:200 - 300:400)
        [1] => 
        [2] => Foo
    ) 

Жирный это то, что я пытаюсь соответствовать: Foo's (match11) это (100: 200 - 300: 400) конец # 1
Foo имеет (not_matched) (100: 200 - 300): 400) конец # 2
Foo (100: 200 - 300: 400) конец # 3
примечание:я не пытаюсь сопоставить # 1, # 2, # 3 в конце каждой строки, это просто для справки.

Если "(100: 200 - 300: 400)" найдено, тополучить любой текст перед ним, иначе "(not_matched) (100: 200 - 300: 400)" найден, затем получить любой текст перед ним, иначе получить текст перед "(100: 200 - 300: 400)"

Другая часть "(not_matched) (100: 200 - 300: 400)" может быть идентифицирована, так как она имеет только 1 пробел между 2 круглыми скобками not_matched и (100: 200 - 300: 400)


Редактировать:

Это то, что я придумала, и это, кажется, работает, хотя для того, чтобы быть полезным, нужны некоторые обходные пути в php.1044 *

(.+)\s\(\w+\)\s\(|(.+)\s\(\d{3}\:\d{3}\s\-\s\d{3}\:\d{3}\)

Рабочий пример: http://www.rubular.com/r/NSpGcnyg0p
По какой-то причине это, похоже, не спасло мой пример, так что вы будетенужно скопировать / вставить его.

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

Кто-нибудь может увидеть, что я делаю неправильно в своем регулярном выражении?

Ответы [ 6 ]

1 голос
/ 03 февраля 2011

Попробуйте это:

^.*?(?=\s*(?:\(not_matched\)\s)?\(\d+:\d+\s*-\s*\d+:\d+\))

или, в PHP:

if (preg_match(
    '/^                   # Anchor the match at start of line
    .*?                   # Match any number of characters lazily
    (?=                   # until just before the following:
     \s*                  # - optional whitespace
     (?:                  # - the following group:
      \(not_matched\)\s   #    - literal (not_matched), followed by 1 whitespace
     )?                   #   (which is optional)
     \(\d+:\d+\s*-\s*\d+:\d+\) # a group like (nnn:mmm - ooo:ppp)
    )                     # End of lookahead assertion
    /x', 
    $subject, $regs)) {
    $result = $regs[0];
} else {
    $result = "";
}
0 голосов
/ 03 февраля 2011

Тройка проверена, в нескольких версиях.

<code><?php

    $string[] = "Foo's (match11) this (100:200 - 300:400) ";
    $string[] = "Foo has (not_matched) (100:200 - 300:400) ";
    $string[] = "Foo (100:200 - 300:400) ";

    $reg = "~(.*)(\([^\)]*\))?\s\(\d{3}\:\d{3}\s\-\s\d{3}\:\d{3}\)~iU";

    foreach ( $string as $s ){
        preg_match_all ( $reg, $s, $m , PREG_SET_ORDER);

        print "<br />String: ". $s . "<br /><pre>";
        print_r ( $m );
        print "

ИЛИ "; print "Требуемая строка:". $ m [0] [1]. "
"; } ?>

Это работает, и вы можете получить необходимую строку на

$output = $m[0][1];
0 голосов
/ 03 февраля 2011

Следующий шаблон будет соответствовать всему, результат сохраняется в ключе wanted:

$PATTERN = '/
    (?P<wanted>.*?)\s* # everything
    (\(.+\s.+\)\s+)? # maybe followed by
    (?= # that ends with
        \(\d{3}:\d{3}\s-\s\d{3}:\d{3}\)
    )
    /x';
preg_match($PATTERN, "Foo's (match11) this (100:200 - 300:400) the end", $matches);
var_dump($matches['wanted']);
preg_match($PATTERN, "Foo has (not matched) (100:200 - 300:400) the end", $matches);
var_dump($matches['wanted']);
preg_match($PATTERN, "Foo (100:200 - 300:400) the end", $matches);
var_dump($matches['wanted']);
0 голосов
/ 31 января 2011

Это, кажется, работает, но нуждается в небольшом обходном пути, чтобы быть полезным в php.(прочитайте мой оригинальный вопрос).

Я выберу это как ответ, если у кого-то еще нет идей ...

(.+)\s\(\w+\)\s\(|(.+)\s\(\d{3}\:\d{3}\s\-\s\d{3}\:\d{3}\)
0 голосов
/ 30 января 2011

Если я четко понимаю, это должно сработать:

/^(.+)(?:\(not_matched\)\s)?(?:\(\d+:\d+\s-\s\d+:\d+\))\s.+\s(#\d+)$/i
0 голосов
/ 30 января 2011

Это будет соответствовать вашему второму примеру: (.+)(\([\D]+\).+)(\#\d+).

И этот будет соответствовать двум другим: (.+)(\([\d\W]+\).+)(\#\d+).

...