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

时间:2016-03-22 13:22:02

标签: regex bash shell

我正在寻找一种简化多个字符串以便进行正则表达式搜索的方法,这是一个例子:

我有几千个字符串的列表,类似于下面的字符串(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

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

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

4 个答案:

答案 0 :(得分:0)

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

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

比你能快速搜索

fgrep -f filter file-to-search-in

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

答案 1 :(得分:0)

以下是您应该了解的一些事项:

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

    就是这样:

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

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

  2. 你说" BASH",所以值得指出正则表达式和文件通配符之间存在差异。如果您正在使用的内容是文本,则可以使用正则表达式(^area.\d+$)。如果你正在使用的东西是文件名,那么globbing (*.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
    

答案 2 :(得分:0)

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 ' ' '|'

答案 3 :(得分:0)

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

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

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