首页 文章

preg_match_all多行不起作用

提问于
浏览
1

我有一个包含换行符的字符串 mystring

when HTTP_REQUEST {
switch -glob [string tolower [HTTP::host]] {
    "sub1.sub.dom" {
    pool /networkname/hostname_80
    }
    "sub2.sub.dom" {
    pool /anothernetworkname/anotherhostname_80
    }
    default {
         drop 
    }
}
}

我正在尝试使用 preg_match_all 从该字符串中提取池但我无法得到想要的结果...我正在使用:

preg_match_all('/\/([^"]+)$/m',$mystring,$result);

结果是:

Array
(
[0] => networkname/hostname_80
    }
[1] => anothernetworkname/anotherhostname_80
    }
    default {
         drop 
    }
}
})

我有两个问题:

  • 为什么数组的第二个元素与第一个元素不相似?考虑到我使用相同的正则表达式这一事实?

  • 如何才能获得没有括号和后面所有东西的池(正则表达式应该在一行的最后一位之后停止匹配) .

谢谢 .

2 回答

  • 2

    看来你只想在一个单词 pool ,1个空格和 / 之后提取非空白字符块 .

    你可以用

    '~\bpool\h+/\K\S+$~m'
    

    在PHP中使用 preg_match_all 函数 . 见regex demo .

    Details

    • \bpool - 整个单词 pool (下一个字符应该是水平空格, \b 是单词边界)

    • \h+ - 1个水平空白字符

    • / - 一个 / char

    • \K - 匹配重置运算符以丢弃到目前为止匹配的文本

    • \S+ - 除了空白之外的1个字符

    • $ - 行尾(由于 m 修饰符) .

    PHP demo

    $re = '~\bpool\h+\K/\S+$~m';
    $str = "when HTTP_REQUEST {\nswitch -glob [string tolower [HTTP::host]] {\n    \"sub1.sub.dom\" {\n    pool /networkname/hostname_80\n    }\n    \"sub2.sub.dom\" {\n    pool /anothernetworkname/anotherhostname_80\n    }\n    default {\n         drop \n    }\n}\n}";
    if (preg_match_all($re, $str, $matches)) {
        print_r($matches[0]);
    }
    

    输出:

    Array
    (
        [0] => networkname/hostname_80
        [1] => anothernetworkname/anotherhostname_80
    )
    
  • 1

    Wiktor正则表达式是正确的,但它在 \S 之后缺少 . ,请参阅preg_match_all Demo

    /\bpool\h+\K\S.+$/m
    

    正则表达式说明:

    • \ b在字边界处断言位置(^ \ w | \ w $ | \ W \ w | \ w \ W)池与字符池完全匹配(区分大小写)

    • \ h匹配任何水平空白字符(等于[[:blank:]])

    • 量词 - 在一次和无限次之间匹配,尽可能多次,根据需要回馈(贪婪)

    • \ K重置报告的匹配的起点 . 最终匹配中不再包含任何先前消费的字符

    • \ S匹配任何非空白字符(等于[^\ r \ n \ n \ t \ f \ v])

    • . 匹配任何字符(行终止符除外)

    • 量词 - 在一次和无限次之间匹配,尽可能多次,根据需要回馈(贪婪)

    • $在一行末尾断言位置

    Global pattern flags

    • m修饰符:多行 . 导致^和$匹配每行的开头/结尾(不仅是字符串的开头/结尾)

相关问题