Извлечь часть шаблона соответствия строк - регулярное выражение, закрыть, но без сигары - PullRequest
1 голос
/ 30 октября 2011

У меня есть строка, которая может быть очень длинной и содержать различные строки и символы.

Я хочу извлечь все строки, которые окружены SB & EB:

SB1EB
SBa description of various lengthEB
SB123.456.78EB
SB99.99EB
SB99.99EB
SB2EB
SBanother description of various lengthEB
SB123.456.00EB
SB199.99EB
SB199.99EB
3
another description of various length that I don't want to return
123.456.00
599.99
599.99
SB60EB
SBanother description of various length that i want to keepEB
SB500.256.10EB
SB0.99EB
SB0.99EB
another bit of text that i don't want - can span multiple lines

Thisэто шаблон, который я использую в PHP:

preg_match_all('/SB(\d+)EB\nSB(\w.*)EB\nSB(\d{3}\.\d{3}\.\d{2})EB\nSB(\d.*)EB\nSB(\d.*)EB\n/', $string, $matches)

Так что, надо надеяться, это вернет:

[0] -> SB1EB
SBa description of various lengthEB
SB123.456.78EB
SB99.99EB
SB99.99EB

[1] -> SB2EB
SBanother description of various lengthEB
SB123.456.00EB
SB199.99EB
SB199.99EB

[2] -> SB60EB
SBanother description of various length that i want to keepEB
SB500.256.10EB
SB0.99EB
SB0.99EB

Но я, очевидно, что-то делаю не так, потому что он ничего не соответствуетМожет кто-нибудь помочь, пожалуйста?

РЕШЕНИЕ:

Основано на ответе @Sajid:

if (preg_match_all('/(?:SB.+?EB(?:[\r\n]+|$))/', $string, $result)) {

    for($i=0;$i<count($result[0]);$i++){

        $single_item = $result[0][$i];
        $single_item = str_replace("SB","",$single_item);
        $single_item = str_replace("EB","",$single_item);
        if (preg_match('/(\d{3}\.\d{3}\.\d{2})/', $single_item)) {

            $id = $single_item;
            $qty = $result[0][$i-2];
            $name = $result[0][$i-1];
            $price = $result[0][$i+1];
            $total = $result[0][$i+2];

        }

    }

}

Это немного грязно, но работает!:)

Спасибо

Ответы [ 3 ]

1 голос
/ 30 октября 2011

Немного взломать, но это сделает работу:

$a = array();    
if (preg_match_all('/(?:SB.+?EB(?:[\r\n]+|$)){5}/', $x, $a)) {
    print_r($a);
}

Обратите внимание, что?: Используется для того, чтобы группа не была захвачена, и результаты будут в $ a [0] (например, $ a [0] [0], $ a [0] [1], $ a [0] [2] ...)

1 голос
/ 31 октября 2011

Основано на @ Саджид ответ :

if (preg_match_all('/(?:SB.+?EB(?:[\r\n]+|$))/', $string, $result))
{
    for ($i=0; $i<count($result[0]); $i++)
    {
        $single_item = $result[0][$i];
        $single_item = str_replace("SB","",$single_item);
        $single_item = str_replace("EB","",$single_item);
        if (preg_match('/(\d{3}\.\d{3}\.\d{2})/', $single_item))
        {
            $id = $single_item;
            $qty = $result[0][$i-2];
            $name = $result[0][$i-1];
            $price = $result[0][$i+1];
            $total = $result[0][$i+2];
        }
    }
}

Это немного грязно, но работает!:)

0 голосов
/ 30 октября 2011
preg_match_all('/SB\d+EB.*?(?=(?:SB\d+EB)|$)/s', $subject, $result, PREG_PATTERN_ORDER);
for ($i = 0; $i < count($result[0]); $i++) {
    # Matched text = $result[0][$i];
}

Итак, в основном, что я делаю (основываясь на ваших входных данных), просто проверяю строку заголовка SB \ d + EB в качестве точки входа и потребляю все, пока не найду другой «заголовок» или конец ввода. Обратите внимание на модификатор / s, чтобы. соответствует переводу строк.

Пояснение:

# SB\d+EB.*?(?=(?:SB\d+EB)|$)
# 
# Options: dot matches newline
# 
# Match the characters “SB” literally «SB»
# Match a single digit 0..9 «\d+»
#    Between one and unlimited times, as many times as possible, giving back as needed (greedy) «+»
# Match the characters “EB” literally «EB»
# Match any single character «.*?»
#    Between zero and unlimited times, as few times as possible, expanding as needed (lazy) «*?»
# Assert that the regex below can be matched, starting at this position (positive lookahead) «(?=(?:SB\d+EB)|$)»
#    Match either the regular expression below (attempting the next alternative only if this one fails) «(?:SB\d+EB)»
#       Match the regular expression below «(?:SB\d+EB)»
#          Match the characters “SB” literally «SB»
#          Match a single digit 0..9 «\d+»
#             Between one and unlimited times, as many times as possible, giving back as needed (greedy) «+»
#          Match the characters “EB” literally «EB»
#    Or match regular expression number 2 below (the entire group fails if this one fails to match) «$»
#       Assert position at the end of the string (or before the line break at the end of the string, if any) «$»
...