php - 如何扩展正则表达式以查找多个匹配项?

标签 php regex icalendar

这是我当前的正则表达式(用于解析 iCal 文件):

/(.*?)(?:;(?=(?:[^"]*"[^"]*")*[^"]*$))([\w\W]*)/

使用 preg_match() 的当前输出是这样的:

//Output 1 - `preg_match()`
Array
(
    [0] => TZID="Greenwich Mean Time:Dublin; Edinburgh; Lisbon; London"
    [1] => VALUE=DATE;RSVP=FALSE;LANGUAGE=en-gb
)

我想扩展我的正则表达式来输出这个(即找到多个匹配项):

//Output 2
Array
(
    [0] => TZID="Greenwich Mean Time:Dublin; Edinburgh; Lisbon; London"
    [1] => VALUE=DATE
    [2] => RSVP=FALSE
    [3] => LANGUAGE=en-gb
)    

正则表达式应搜索不包含在带引号的子字符串中的每个分号,并将其作为匹配项提供。


不能仅仅交换到 preg_match_all() 因为会产生这个不需要的输出

//Output 3 - `preg_match_all()`
Array
(
    [0] => Array
        (
            [0] => TZID="Greenwich Mean Time:Dublin; Edinburgh; Lisbon; London";VALUE=DATE;RSVP=FALSE;LANGUAGE=en-gb
        )

    [1] => Array
        (
            [0] => TZID="Greenwich Mean Time:Dublin; Edinburgh; Lisbon; London"
        )

    [2] => Array
        (
            [0] => VALUE=DATE;RSVP=FALSE;LANGUAGE=en-gb
        )

)

最佳答案

您需要使用preg_match_all来获取字符串的所有匹配项。

您使用的模式并不是为了获得多个结果而设计的,因为 [\w\W]* 匹配字符串末尾之前的所有内容。
但这只是你的问题之一,像这样设计的模式需要检查(对于每个冒号)引号的数量是奇数还是偶数,直到文件末尾!: (?=(?:[^"]*"[^"]*")*[^"]*$)。想象一下,一分钟内整个字符串被此先行解析了多少次。

为了避免这个问题,您可以使用不同的方法,不尝试查找冒号,而是尝试描述不是冒号的所有内容:因此,您正在寻找无论内容如何,​​不包含引号或冒号+引号部分的文本。

您可以使用这种模式:

$pattern = '~[^\r\n";]+(?:"[^"\\\]*(?:\\\.[^"\\\]*)*"[^\r\n";]*)*~';

if (preg_match_all($pattern, $str, $matches))
    print_r($matches[0]);

图案详细信息:

~           # pattern delimiter
[^\r\n";]+  #" # all that is not a newline, a double quote or a colon
(?:         # non-capturing group: to include eventual quoted parts
    "                  #"# a literal quote
    [^"\\\]*           #"# all that is not a quote or a backslash
    (?:\\\.[^"\\\]*)*  #"# optional group to deal with escaped characters
    "                  #"#
    [^\r\n";]*         #"# 
)*          # repeat zero or more times 
~

demo

关于php - 如何扩展正则表达式以查找多个匹配项?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30601347/

相关文章:

javascript - 如何根据xml数据移动表格中的单元格?

regex - 如何删除特定字符前后的文本?

jquery - mvc3 View 中的电子邮件格式验证

php - MySQL 更新功能不工作

php - 在没有API PHP的情况下获取Youtube用户名

php - 在 PHP 中获取 Google 日历事件

sharepoint - 从 SharePoint 工作流安排约会

javascript - 当我将 "METHOD: REQUEST"添加到 iCalendar 时,Gmail 停止识别为事件

php - mysqli_fetch_array() - 添加另一列来匹配时出错

javascript - 替换 JavaScript 字符串中的所有加号