我正试图使用perl regexp对图书馆数据库的搜索日志中的搜索字符串进行规范化处理,我需要删除所有出现的数字,将是。
s/\d*//g
除了 当我有一个出生日期,如1964-或一生,如1903-1970或1903-70.我怎么做?
你可以使用 旁观论断.
例如,以下模式
/\b(?<!-)\d+(?!-)\b/
会匹配一个数字,如 42
或 1970
但不匹配。
例如,给定一个输入。
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
一个复杂的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;
你的意思是把所有的数字都替换掉 除了数字的格式是: 1000-
或 1000-90
?
试试这个
(?<!\d)(?<!-)\d+(?!-\d*)(?!\d)