维护特殊模式的出现 regex perl

问题描述 投票:2回答:3

我正试图使用perl regexp对图书馆数据库的搜索日志中的搜索字符串进行规范化处理,我需要删除所有出现的数字,将是。

s/\d*//g 

除了 当我有一个出生日期,如1964-或一生,如1903-1970或1903-70.我怎么做?

regex perl digits
3个回答
1
投票

你可以使用 旁观论断.

例如,以下模式

/\b(?<!-)\d+(?!-)\b/

会匹配一个数字,如 421970 但不匹配。

  • 1964-
  • 1903-1970
  • 1903-70

例如,给定一个输入。

42 foo 123 1964- 1903-1970 456 bar 1970

用上面的regex去掉要输入的字符串。

$ echo 42 foo 123 1964- 1903-1970 456 bar 1970 | perl -pe 's/\b(?<!-)\d+(?!-)\b//g'
 foo  1964- 1903-1970  bar

1
投票

一个复杂的regex可以解决这个问题,当然。 然而,我相信最简单的解决方案是利用正则表达式中最强大的工具之一,即贪婪匹配,并将其分为两步。

s{([-\d]+)}{my $num = $1; $num =~ /^(?:\d+-\d*|-+)$/ ? $num : ''}eg;

LHS拉出任何数字和或破折号。 然后RHS如果它们符合你所要求的特定异常,就把它们留下。

我喜欢这两步解决方案,因为它能更快地看到发生了什么,而且regex也不那么脆弱,所以在以后的时间里更容易调整它,引入bug的风险更小。 你要做的就是在RHS中添加你想要的额外的异常。

通过添加大量的边界条件来反映贪婪匹配的效果,可以只用LHS来重复上面的内容。 下面演示了这一点。

s{
    (?<![-\d])     # Start Boundary Condition to Enforce Greedy Matching
    (?!
        (?:          # Old RHS: List of expressions we don't want to match
            \d+-\d*
        |
            -+
        )
        (?![-\d])   # End Boundary Condition to Enforce Greedy Matching
    )
    ([-\d]+)      # Old LHS: What we want to match
    (?![-\d])     # End Boundary Condition to Enforce Greedy Matching
}{}xg;

0
投票

你的意思是把所有的数字都替换掉 除了数字的格式是: 1000-1000-90?

试试这个

(?<!\d)(?<!-)\d+(?!-\d*)(?!\d)
© www.soinside.com 2019 - 2024. All rights reserved.