使用 Bash RegEx 和 Grep 时遇到问题 – 需要帮助

Having Trouble with Bash RegEx and Grep – Need Assistance

提问人:PopSmoke 提问时间:9/3/2023 最后编辑:InSyncPopSmoke 更新时间:9/4/2023 访问量:62

问:

我正在尝试编写一个使用 RegEx 模式并将其作为输入的 bash 脚本:

  #
  #------------------------------------------- spaceholder ---------------------------------------------------------------------------
  #

  #@E2E-1 @id:1 
  Scenario: Login & Search: B2B_PKG_IN >> BE
    Given I am on the login page
    When I enter <username> and incorrect password multiple times
    Then I should be locked out of my account
    And I should see a lockout message



  #@E2E-2 @id:32 
  Scenario: Login & Search: B2B_PKG_IN >> NL
    Given I am on the login page
    When I enter <username> and incorrect password multiple times
    Then I should be locked out of my account
    And I should see a lockout message


  #
  #------------------------------------------- B2B_PKG_3PA ---------------------------------------------------------------------------


  #

  @E2E-3 @id:3
  Scenario: Login & Search: B2B_PKG_3PA >> BE
    Given I am on the login page
    When I enter <username> and incorrect password multiple times
    Then I should be locked out of my account
    And I should see a lockout message

我用这个 chatgpt 生成的模式测试了它:((@[^\n]+|#@[^\n]+)?\s*)?Scenario:[^\n]*\n(?:[^\n]*\n)*?\n

它的工作方式就像我想要的那样,输出在正则表达式测试网站上如下所示:

  #@E2E-1 @id:1 
  Scenario: Login & Search: B2B_PKG_IN >> BE
    Given I am on the login page
    When I enter <username> and incorrect password multiple times
    Then I should be locked out of my account
    And I should see a lockout message



  #@E2E-2 @id:32 
  Scenario: Login & Search: B2B_PKG_IN >> NL
    Given I am on the login page
    When I enter <username> and incorrect password multiple times
    Then I should be locked out of my account
    And I should see a lockout message



  @E2E-3 @id:3
  Scenario: Login & Search: B2B_PKG_3PA >> BE
    Given I am on the login page
    When I enter <username> and incorrect password multiple times
    Then I should be locked out of my account
    And I should see a lockout message

所以现在我在 bash 中尝试了 grep,如下所示:

while IFS= read -r -d '' block; do
        current_scenarios+=("$block")
    done < <(grep -Pzo "$pattern" "$current_file")

由于某种原因,它包括 #space 支架部分,我尝试过,但似乎没有任何效果,请帮忙grep -Egrep -oPgrep -Po

正则表达式 bash grep

评论

0赞 Cyrus 9/3/2023
请查看如何使用 Markdown 或 HTML 格式化我的帖子?

答:

2赞 Ed Morton 9/3/2023 #1

请记住这句话

有些人在遇到问题时会想“我知道,我会使用正则表达式。现在他们有两个问题。

您在线生成或验证的任何正则表达式都不能保证适用于每个命令行工具,如果它是一个复杂的正则表达式,尤其是您想要跨越多个输入行的正则表达式,那么可能有更好的方法来执行您想要的任何事情。

使用任何 awk:

$ awk -v RS= -v ORS='\n\n' '$1 ~ /^#?@/' file
  #@E2E-1 @id:1
  Scenario: Login & Search: B2B_PKG_IN >> BE
    Given I am on the login page
    When I enter <username> and incorrect password multiple times
    Then I should be locked out of my account
    And I should see a lockout message

  #@E2E-2 @id:32
  Scenario: Login & Search: B2B_PKG_IN >> NL
    Given I am on the login page
    When I enter <username> and incorrect password multiple times
    Then I should be locked out of my account
    And I should see a lockout message

  @E2E-3 @id:3
  Scenario: Login & Search: B2B_PKG_3PA >> BE
    Given I am on the login page
    When I enter <username> and incorrect password multiple times
    Then I should be locked out of my account
    And I should see a lockout message
0赞 tshiono 9/4/2023 #2

若:

  • 每个块都以 或 开头的行开头。#@@
  • 块中的下一行以字符串 .Scenario:
  • 块之间不包含空行。
  • 如果后跟两个或多个空行(或文件的末尾),则块结束。
  • 您希望为具有匹配块的 bash 数组分配一个 bash 数组。current_scenarios
  • 每行外观包含两个前导空格, 但这是一个编辑问题,可以忽略。$current_file

那么请你试试:

pattern="(?sm)^#?@[^\n]+\n*^Scenario:.*?\n(?=\n{2}|\n*\Z)"
while IFS= read -r -d '' block; do
    current_scenarios+=("$block")
done < <(grep -Pzo "$pattern" "$current_file")

printf "%s\n\n" "${current_scenarios[@]}"       # just to see the results

正则表达式的解释:(?sm)^#?@[^\n]+\n*^Scenario:.*?\n(?=\n{2}|\n*\Z)

  • 该选项使点匹配换行符。(?s).
  • 该选项使并匹配行的开始/结束, 以及输入字符串的开始/结束。(?m)^$
  • ^#?@匹配行或行首。#@@
  • [^\n]+\n*消耗当前行。
  • ^Scenario:匹配下一行。
  • .*?\n匹配以下行,尽可能短(非贪婪)。
  • (?=\n{2}|\n*\Z)是与两个空白匹配的前瞻断言 行或输入的末尾。