正则表达式 (BASH) 的字符串简化



我正在寻找一种简化多个字符串以用于正则表达式搜索的方法,下面是一个例子:

我有一个包含数千个字符串的列表,类似于下面的字符串(text.#######):

area.202264
area.202265
area.202266
area.202267
area.202268
area.202269
area.202270
area.204517
area.204518
area.204519
area.207171
area.207338
area.208842

我一直在试图找出一种自动化的方法来将其简化为这样的东西:

area.20226(4|5|6|7|8|9)|area.202270|area.20451(7|8|9)|area.207171|area.207338|area.208842

这样做的目的是在搜索这些区域时减少字符串长度,我绝对没有办法以简单、可重用的方式处理这样的事情。

提前感谢!任何关于从哪里开始的解决方案或提示将不胜感激:)

echo "area.202264 area.202265 area.202266 area.202267 area.202268 area.202269 area.202270 area.204517 area.204518 area.204519 area.207171 area.207338 area.208842" | tr ' ' 'n' > list.txt
cat list.txt | grep -v "^$" | sed -e "s/[0-9] *$//g" | sort -u | while read p; do l=`grep $p list.txt | sed -e "s/.*([0-9])$/1/g" | xargs |  tr ' ' '|'` ;echo "$p($l)" ; done | sed -e "s/((.))/1/g"| xargs| tr ' ' '|'

将搜索字符串放在一列中名为"filter"的文件中

area.202264
area.202265
area.202266
area.202267 

比您可以搜索的速度足够快

fgrep -f filter-file-to-search-in

我认为没有简单的方法可以从样本中生成正则表达式,而且我不确定正则表达式方法会更快。

以下是您应该知道的几件事:

  1. 几乎所有正则表达式引擎都根据其模式构建状态机。您可能只需将各种名称放在垂直条之间即可获得良好的性能。(它看起来不太好,但它会起作用。

    也就是说,类似于:

    (area.202264|area.202265|area.202266|...|area.207338|area.208842)
    

    即使有 4k 项,正确的引擎也会将其编译下来。(我不认为bash会处理它,因为长度。但是其他地方提到的perl,grep,fgrep可以做到这一点。

  2. 你说"BASH",所以值得指出的是正则表达式和文件通关之间存在差异。如果您正在使用的东西是文本,那么正则表达式(^area.d+$)就是要走的路。如果您正在使用的内容是文件名,则通配(*.c)有不同的规则。

  3. 如果您根本不关心数字,只关心格式,您可以大大简化。对于正则表达式:

    area.d+      # area, dot, one or more digits (0-9)
    area.d{1,6}  # area, dot no less than 1, no more than 6 digits
    area.d{6}    # area, dot, exactly 6 digits
    area.20[234]d{3}  # area, dot, 20 {2,3,4} then 3 more digits
    

如果你可以使用Perl和Regexp::Assemble模块,它可以将多个模式转换为单个优化的正则表达式。 例如,在问题中的字符串列表中使用它会产生:

(?-xism:area.20(?:22(?:6[456789]|70)|7(?:171|338)|451[789]|8842))

这只有在数据库插件可以接受 Perl 正则表达式时才有效。

最新更新