正则表达式预测复杂模式

时间:2015-07-08 20:03:05

标签: php regex

此代码用双管替换太多单管。为了保持较小的变化,我宁愿简单地纠正第二个正则表达式,以便它允许“|”之间的空格和“,”。

所以,问题是如何将第二个正则表达式修改为 not 匹配\|[[:blank:]]*[^,\r\n]

代码:

$patterns = array (
  '/\\\\\|,/', 
  "/(?<=[^,])\|(?=[^,\n\r])/"
);
$replacements = array (
  '|,', 
  '||'
);
$line = preg_replace ($patterns, $replacements, $line);

示例:

对于字符串:"|DI|,|15| ,|C00413914|,|| ,|F|"

预期/期望的结果:

"|DI|,|15| ,|C00413914|,|| ,|F|"

实际结果:

"|DI|,|15|| ,|C00413914|,||| ,|F|"

我试过这个,但没效果:

  • "/(?<=[^,])\|(?=[[:blank:]]*[^,\n\r])/"

请注意:

这个问题是用尽可能小的修改来修复bug。当前的正则表达式可能不是最理想的(比如使用负字符类而不是负面的外观),但我的首要任务是最小化更改而不是优化正则表达式。

更新

换句话说,基于我对原始正则表达式的解释,修订版应匹配任何单个|后跟零或更多空格,这些空格不在行的开头或结尾,不以逗号开头,而不是,\r\n

更多示例:

  1. 5|foo应匹配
  2. 5| foo应匹配
  3. 5|,不匹配
  4. 5| ,不匹配
  5. 5|\r不匹配
  6. 5| \r不匹配
  7. ,||,不匹配
  8. ,|| ,不匹配
  9. 从将建议应用于实际数据后发现。原始正则表达式似乎观察到了这种行为:

    1. |foo|,不匹配。管道是第一个在线字符。
    2. |foo| ,不匹配。管道是第一个在线字符。
    3. ,|foo|不匹配。管道是最后一个字符在线,换行可能不存在(例如使用EOF)。
    4. ,|foo|不匹配。 Pipe +空格是行上的最后一个字符,换行可能不存在(例如使用EOF)。

2 个答案:

答案 0 :(得分:0)

试试这个:

(?<=[^,])\|(?=[^,\n\r ])

如果这不是您的意思,请提供更多输入和所需的输出示例。

答案 1 :(得分:0)

您在开始时寻找的正则表达式可以写成

(?<!,)\|(?![[:blank:]]*[,\n\r])

如果没有可选的空格后跟逗号或换行符,则匹配管道,并且前面没有逗号。

请注意,在这个正则表达式示例中,我们不需要占有量词,因为在PHP的前瞻中,由于内部优化,默认情况下会占用所有权行为。

您的最终正则表达式也可能看起来像

(?<=[^\r\n,])\|(?=[[:blank:]]*+[^,\n\r])

它检查管道前面是否有逗号或换行符以外的字符,后跟0或更多空格后面没有commq或换行符。如果您的PCRE库是在没有优化的情况下编译的,则可以使用*+强制拥有行为。