【问题标题】:Split line into multiple parts using regex使用正则表达式将行拆分为多个部分
【发布时间】:2019-04-11 08:33:06
【问题描述】:

我有一个类似

的字符串
BK0001 My book (4th Edition) $49.95 (Clearance Price!)

我想要一种方法将其拆分为不同的部分,例如

[BK0001] 
[My Book (4th Edition)] 
[$49.95] 
[(Clearance Price!)]

我对正则表达式很陌生,我正在使用它来解析文件中的一行。我设法通过使用

获得了第一部分 BK0001
$parts = preg_split('/\s+/', 'BK0001 My book (4th Edition) $49.95 (Clearance Price!)';

然后获取 $part[0] 值,但不确定如何拆分它以获取其他值。

【问题讨论】:

  • 你用过regex101吗?学习正则表达式和针对特定需求进行开发的绝佳资源。
  • 尝试拼出子模式。比如preg_match('~^(?<code>\S+)\s+(?<name>.*?)\s+(\$\d[\d.]*)\s*(?<details>.*)$~', $text, $matches),见demo
  • @Dan Farrel 我有,但我不经常使用 php 和正则表达式,我主要在 python 中编写代码,通常使用 string.split() 来完成诸如此类的任务。这是我需要正则表达式并投入时间学习它的罕见时刻之一,这确实是一个很好的选择。
  • @WiktorStribiżew 完美运行。谢谢
  • learning it fully really a good option right now 学习正则表达式总是很好,大多数语言都有它的味道,而且非常强大和有用。

标签: php regex split preg-split


【解决方案1】:

尝试使用 preg_match

$book_text = "BK0001 My book (4th Edition) $49.95 (Clearance Price!)";
if(preg_match("/([\w\d]+)\s+(.*?)\s+\\((.*?)\\)\s+(\\$[\d\.]+)\s+\\((.*?)\\)$/",$book_text,$matches)) {
    //Write code here
    print_r($matches);
}

$matches[0] 为完整匹配字符串保留。您可以从 $matches[1] 中找到拆分部分...

Array ( [0] => BK0001 My book (4th Edition) $49.95 (Clearance Price!) [1] => BK0001 [2] => My book [3] => 4th Edition [4] => $49.95 [5] => Clearance Price! )

$matches[1] is "book number"
$matches[2] is "book name"
$matches[3] is "edition"
$matches[4] is "price"
$matches[5] is "special text"

【讨论】:

    【解决方案2】:

    您可以使用带有捕获组的单个模式匹配输入字符串的特定部分:

    preg_match('~^(?<code>\S+)\s+(?<name>.*?)\s+(?<num>\$\d[\d.]*)\s*(?<details>.*)$~', $text, $matches)
    

    请参阅regex demo。实际上,最后一个$ 不是必需的,它只是为了显示整个字符串匹配。

    详情

    • ^ - 字符串开头
    • (?&lt;code&gt;\S+) - 组“代码”:一个或多个非空白字符
    • \s+ - 1+ 个空格
    • (?&lt;name&gt;.*?) - 组“名称”:除换行符之外的任何 0+ 个字符,尽可能少
    • \s+ - 1+ 个空格
    • (?&lt;num&gt;\$\d[\d.]*) - 组“num”:$,然后是 1 位数字,然后是 0+ 位数字或 .
    • \s* - 0+ 个空格
    • (?&lt;details&gt;.*) - 组“详细信息”:除换行符之外的任何 0+ 字符,尽可能多
    • $ - 字符串结束。

    PHP code:

    $re = '~^(?<code>\S+)\s+(?<name>.*?)\s+(?<num>\$\d[\d.]*)\s*(?<details>.*)$~';
    $str = 'BK0001 My book (4th Edition) $49.95 (Clearance Price!)';
    if (preg_match($re, $str, $m)) {
        echo "Code: " . $m["code"] . "\nName: " . $m["name"] . "\nPrice: " .
             $m["num"] . "\nDetails: " . $m["details"]; 
    }
    

    输出:

    Code: BK0001
    Name: My book (4th Edition)
    Price: $49.95
    Details: (Clearance Price!)
    

    【讨论】:

    • @answerSeeker,这是 regex101 链接的强大之处。您始终可以在问题中包含相同的内容。
    猜你喜欢
    • 2019-05-14
    • 2014-01-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多