【问题标题】:Capturing groups in string using preg_match使用 preg_match 捕获字符串中的组
【发布时间】:2020-01-19 16:32:28
【问题描述】:

我在 codeigniter 中解析文本文件时遇到了麻烦,对于文件中的每一行我需要捕获组数据...数据是: - 渐进式数字 - 操作员 - 制造商 - 模型 - 登记 - 类型

这是文件行的示例

 8  SIRIO S.P.A.                                             BOMBARDIER INC.                                       BD-100-1A10             I-FORZ              STANDARD

 9  ESERCENTE PRIVATO                                        PIAGGIO AERO INDUSTRIES S.P.A.                        P.180 AVANTI II         I-FXRJ              SPECIALE/STANDARD

10  MIGNINI & PETRINI S.P.A.                                 ROBINSON HELICOPTER COMPANY                           R44 II                  I-HIKE              SPECIALE/STANDARD

11  MIGNINI & PETRINI S.P.A.                                 ROBINSON HELICOPTER COMPANY                           R44 II                  I-HIKE              STANDARD

12  BLUE PANORAMA AIRLINES S.P.A.                            THE BOEING COMPANY                                    737-86N                 I-LCFC              STANDARD

要解析每一行,我使用以下代码:

if ($fh = fopen($filePath, 'r')) {
    while (!feof($fh)) {
        $line = trim(fgets($fh));

        if(preg_match('/^(\d{1,})\s+(\w{1,})\s+(\w{1,})\s+(\w{1,})\s+(\w{1,})\s+(\w{1,})$/i', $line, $matches))
       {
             $regs[] = array(
             'Operator'     => $matches[1],
             'Manufacturer' => $matches[2],
             'Model'        => $matches[3],
             'Registration' => $matches[4],
             'Type'         => $matches[5]
             );
             $this->data['error'] = FALSE;
        }
    }
    fclose($fh);
 }

上面的代码不起作用...我认为是因为某些数据组由多个单词组成...例如“SIRIO S.P.A.” 有什么提示可以解决这个问题吗? 非常感谢您的帮助

【问题讨论】:

    标签: php regex codeigniter


    【解决方案1】:

    您不应使用\w 来捕获数据,因为您的文本中的某些字符(例如&.-/)不是单词字符的一部分。此外,其中一些是空格分隔的,因此您应该将 \w{1,} 替换为 \S+(?: \S+)*,这会将您的文本正确地捕获到您创建的组中。

    尝试将您的正则表达式更改为此,它应该可以工作,

    ^\s*(\d+)\s+(\S+(?: \S+)*)\s+(\S+(?: \S+)*)\s+(\S+(?: \S+)*)\s+(\S+(?: \S+)*)\s+(\S+(?: \S+)*)$
    

    Check this demo

    解释\S+(?: \S+)* 在上述正则表达式中的作用。

    • \S+ - \S\s 相反,这意味着它匹配任何非空格(不匹配空格或制表符或换行符或垂直空格或水平空格以及通常任何空格)字符。因此\S+ 匹配一个或多个可见字符
    • (?: \S+)* - 这里?: 仅用于将一个组转换为非捕获组,并且在它后面有一个空格和\S+,并且所有这些都用* 量词括在括号中。因此,这意味着在使用* 量词时,匹配一个空格,后跟一个或多个非空白字符,并将其全部匹配零次或多次。

    所以\S+(?: \S+) 将匹配abcabc xyzabc pqr xyz 等等,但当出现多个空格时,匹配停止,因为\S+ 之前的正则表达式中只有一个空格

    希望我的解释清楚。如果仍有疑问,请随时提问。

    【讨论】:

    • 非常感谢Silvanasa,非常感谢...我有很多关于正则表达式的知识。你能解释一下这段代码吗?: (\S+(?: \S+)*)
    • @Federico:添加了解释:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-10
    • 1970-01-01
    相关资源
    最近更新 更多