【问题标题】:Matching specific character if it is between two digits with regex如果特定字符在两个数字之间,则匹配正则表达式
【发布时间】:2016-08-31 20:10:52
【问题描述】:

对于某些数据处理,我需要将一个字符串拆分为多个项目。 输入字符串的示例是:

'one, two & three and four-five 123-456'

现在,我需要将此字符串分隔为多个项目,可能的分隔符为,&(空格)、and-。但是,这就是我被卡住的地方,当它在两个数字之间时,它不应该在 - 上分裂。

我正在使用 PHP 和 preg_split 进行实际拆分,但是当分隔符位于两个数字(数字,但也可以是 123-456)之间时,我需要一个正则表达式模式来匹配不包括分隔符 - 的分隔符.在 PHP 中使用 trim() 来抑制每个项目周围的空格。

我正在使用以下正则表达式模式:

/(and|,|\s|&)|\D(-)\D/

输出(使用preg_split等之后)是:

[0] => one
[1] => two
[2] => three
[3] => fou
[4] => ive
[5] => 123-456

工作是正确的,但它也需要 - 分隔符周围文本的最后一个和第一个字母。 123-456 项是正确的,因为它不应该在 - 立即被数字包围时匹配(并与 preg_split 分开)。

预期输出是:

[0] => one
[1] => two
[2] => three
[3] => four
[4] => five
[5] => 123-456

感谢任何帮助,如果缺少任何信息,请告诉我,我会更新我的问题。

【问题讨论】:

    标签: php regex preg-split


    【解决方案1】:

    您要使用的是lookahead and lookbehind(通常称为环视):

    /and|,|\s|&|(?<!\d)-(?!\d)/
    

    这正是它的名字所暗示的 - 环顾四周以检查指定的模式是否匹配,不匹配。在这种情况下,它只会匹配两边没有被数字字符包围的-\ds),但 match 只会是 - 本身.

    在这种情况下,(?&lt;!\d) 是一个负向回溯 - 它会向后看以查看紧接在前面的字符串是否 匹配模式。如果是,它会将匹配报告为失败并继续前进。同样,(?!\d) 是一个负前瞻——它做的事情完全相同,但方向相反。因为- 夹在它们之间,所以效果是“如果- 两边都没有数字字符,则只匹配它”。

    【讨论】:

    • 谢谢。这解决了我的问题。我会在几分钟后接受你的回答。出于兴趣,第一部分的符号不同的原因是什么?它的工作原理和我的完全一样,但它还有其他作用吗?
    • 最后一个交替边应该是(?&lt;!\d)-(?!\d) 否则它不匹配前导和尾随-
    • @revo:很好。已编辑。
    • @SebastianLenartowicz 感谢您的额外解释。你能解释一下为什么在第一部分and|,|\s|&amp; 周围不需要匹配的() 吗?另外,我试图尽可能地理解这一点,@revo,前导和尾随 - 不会匹配是什么意思?
    • 因为简单的()(方括号)是一个捕获组 - 在您的场景中,不需要它,所以我将其删除。假设您有一个分隔符,它可以是andandson。然后,例如,您可以执行/and(son)?|foo|bar/ 之类的操作 - 括号用于“分组”son,因此它由?(可选)量词作为一个组进行操作。这个正则表达式相当于/and|andson|foo|bar/
    猜你喜欢
    • 2023-04-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-26
    • 2012-07-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多