【问题标题】:Ruby or Bash or Grep regex is not working for '?' i.e. 0 or 1 occurrence of previous characterRuby 或 Bash 或 Grep 正则表达式不适用于“?”即前一个字符出现 0 次或 1 次
【发布时间】:2019-01-10 04:43:43
【问题描述】:

Linux Red Hat Enterprise Linux Server 6.9 版(圣地亚哥)

问题:
我有 2 个 Jenkins 工作,它们都调用另一个常见/可重用的下游工作(使用正则表达式来选择它的 rpm)。实际代码是用 Ruby 编写的(我使用的是 ::Dir.glob("<pattern>",''),但它无法选择正确的 rpm 名称(没有给我任何错误),但这里我只关注正则表达式部分。

job1 中,在我的工作区中,我看到了 myrpm.rpmmyrpm-extra.rpm

job2 中,在我的工作区中,我看到 myrpm-3.0.0.1027-2018_12_21_121519.noarch.rpmmyrpm-extra-3.0.0.1027-2018_12_21_121519.noarch.rpm rpms,这是我通过一些 AQL 从 Artifactory 下载这些文件后获得的。

一旦从 Aritfactory 下载了 rpm,即在 Jenkins 工作区中可用,然后我使用这个常见的下游作业来选择我需要的给定 rpm 使用"${rpmname}*.rpm" 正则表达式。

问题是,当我将rpmname 参数值作为“myrpm”传递时,逻辑选择myrpm-extra.rpm(在Job1) 或 myrpm-extra-3.0.0.1027-2018_12_21_121519.noarch.rpm (Job2) 而不是正确的(非额外的),因为 - 字符的顺序是第一位的,因为 ASCII 序列。

我测试了正则表达式并查看了为什么在最后一个命令中我没有看到预期的输出。正则表达式中的1? 不会给我们任何具有arun0 or 1 出现字符1 的行吗?

[giga@linux-server giga]# echo -e "arun\narun1\narun2\narun11" |grep "arun"
arun
arun1
arun2
arun11
[giga@linux-server giga]#

[giga@linux-server giga]# echo -e "arun\narun1\narun2\narun11" |grep "arun1"
arun1
arun11
[giga@linux-server giga]#

[giga@linux-server giga]# echo -e "arun\narun1\narun2\narun11" |grep "arun1?"
[giga@linux-server giga]#

问题:
1. 如果我使用egrep,为什么会这样?
2. 为什么它不适用于grep,而grep 手册页/示例告诉它支持它?
3. 我可以使用什么正则表达式,这样如果我将myrpm 作为作业参数的值传递,那么它可以在 Job1 和 Job2 中工作,其中 rpm 文件名包含短名称和完整 rpm 名称。

这里:https://www.cyberciti.biz/faq/grep-regular-expressions/(搜索 grep 正则表达式运算符)和

man grep 显示:

   Repetition
       A regular expression may be followed by one of several repetition operators:
       ---------------------------------------------------------------
       ?      The preceding item is optional and matched at most once.
       ---------------------------------------------------------------  
       *      The preceding item will be matched zero or more times.
       +      The preceding item will be matched one or more times.
       {n}    The preceding item is matched exactly n times.
       {n,}   The preceding item is matched n or more times.
       {,m}   The preceding item is matched at most m times.  This is a GNU extension.
       {n,m}  The preceding item is matched at least n times, but not more than m times.

【问题讨论】:

  • grep -E "arun1?" 使用扩展的正则表达式。 BRE 中的 ? 只是文字 ?
  • 手册页中的相关行:In basic regular expressions the metacharacters ?, +, {, |, (, and ) lose their special meaning; instead use the backslashed versions \?, \+, \{, \|, \(, and \).
  • 谢谢@anubhava 有什么表达式可以同时适用于 Job1 和 Job2 的情况吗?

标签: ruby regex linux bash grep


【解决方案1】:

egrepgrep -E 相同,在您的情况下,使用regex,需要-E-P 来支持?

请搜索不同的regex 支持。有POSIXExtendedPerl等。

资源:
POSIX Basic and Extended Regular Expressions
Perl regular expressions
Regular expression

【讨论】:

  • 谢谢@Tiw,我想我找到了解决方案。
【解决方案2】:

最终解决方案: 使用了这个正则表达式模式:${package_name}(?:-[0-9]*)?\..*rpm,代码示例(在 Ruby 中)如下所示。

在 Ruby 中:切换到 rpm 所在的目录后,我得到了这一行来找到正确的 rpm 名称。 注意: 在 Ruby 中,::Dir.glob("<pattern>",..)not a real REGEX pattern,它只是一个 SHELL glob 模式。

  wildcard = "#{new_resource.session['package_name']}(?:-[0-9]*)?\..*#{ext_type}"
rpmfullname = Dir["#{new_resource.session['package_name']}*.#{ext_type}"].select { |f| f =~ /#{wildcard}/ }.sort.first

这个网站帮助很大。 https://rubular.com/ 示例模式为myrpm(?:-[0-9]*)?\..*rpm: 和测试用例字符串为:

myrpm.rpm
myrpm-extra.rpm
myrpm-1.0.0_112233.noarch.rpm
myrpm-11.0.0_112233.noarch.rpm
myrpm-111.0.0_112233.noarch.rpm
myrpm-1.0_112233.noarch.rpm
myrpm-extra-1.0.0_112233.noarch.rpm
foo.yum
berayan.rpm
arun.yum
Toni.rpm
myrpm-1.0.0_112233.rpm

【讨论】:

    猜你喜欢
    • 2015-11-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-29
    • 2014-05-31
    • 2018-06-18
    • 1970-01-01
    • 2015-12-12
    相关资源
    最近更新 更多