Php 提取字符串匹配模式的一部分-正则表达式,关闭但不关闭

Php 提取字符串匹配模式的一部分-正则表达式,关闭但不关闭,php,regex,preg-match-all,Php,Regex,Preg Match All,我有一个字符串,可以很长,包含各种行和字符 我想提取由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

我有一个字符串,可以很长,包含各种行和字符

我想提取由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
这是我在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];

        }

    }

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

对于($i=0;$i有点麻烦,但这样就可以了:

$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]…)

基于:

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

对于($i=0;$i感谢您,但这不起作用,因为我的示例之间可能有其他行我不想返回。我已更新示例以显示这一点。我只想返回以SB开头的行,而不想返回以SB开头的行。@SammyBlackBaron让我回到它;)@SammyBlackBaron您想捕获特定行吗?这比捕获多行文本块要容易得多。让我知道。这基本上是一个格式化为新行的产品详细信息字符串。我想返回数量、名称、ID、价格、总计,因此它必须是5行,并且只有我想要的产品被SB&EB'ta包围正如我在另一条评论中提到的,这是我要提取的文本块的格式:
SB(整数)EB\n SB(文本)EB\n SB(格式为000.000.00的数字)EB\n SB(十进制)EB\n SB(十进制)EB\n
如果我去掉换行符,使其仅为一个长的单行字符串,会有帮助吗?然后匹配与我的原始字符串相似的模式(错误)regex?感谢您的帮助谢谢,这非常接近,但由于某些SB&EB行并不总是以5行为一组,因此生成的数组是不连续的。我确实希望只匹配以SB开头且长度为5行的行,但前提是它们与我的(错误)regex中的模式匹配:
SB(整数)EB\n SB(文本)EB\n SB(数字格式000.000.00)EB\n SB(十进制)EB\n SB(十进制)EB\n
我已经根据您的解决方案获得了所需的数据,但没有{5}部分。谢谢您-我会将我的解决方案添加到我的帖子中,这有点麻烦,但有效!网站告诉我必须等待-“您可以在4小时内接受您自己的答案…”
# 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) «$»
$a = array();    
if (preg_match_all('/(?:SB.+?EB(?:[\r\n]+|$)){5}/', $x, $a)) {
    print_r($a);
}
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];
        }
    }
}