regex - 将重复的正则表达式模式捕获为一组,在 bash 脚本中使用 sed

标签 regex bash shell sed capture-group

我编写了一个工作表达式,从有效的文本行中提取两条数据。第一个捕获组是包含句点的数字部分。第二个是该行的剩余字符,只要该行有效。如果数字部分以句点结尾或行以数字结尾,则该行无效。

1.1 the quick 1-1 (no match due to ending hypen and number)
11.2 brown fox jumped (should return '11.2' and 'brown fox jumped')
1.41.1 over the lazy (should return '1.41.1' and 'over the lazy')
2.1. dog (no match due to numerical section trailing period)

表达式 ^((?:[0-9]+\.)+[0-9]+) (.*)[^0-9]$ 在各种测试中都有效正则表达式测试站点。

我的问题是...我未能调整此表达式以与循环文本行 ($L) 的 bash 脚本中的 sed 一起使用。

IFS=$'\t' read -r NUM STR < <(sed 's#^\(\(?:[0-9]\+\.\)\+[0-9]\+\) \(.*)[^0-9]$#\1\t\2#p;d' <<< $L )

下面的内容是有效的,我用重复的数字和句点替换了重复组的捕获。我不想这样做,因为它可以匹配以句点开头的行和连续的多个句点。它还丢失了捕获字符串的最后一个字符,但我希望我能弄清楚该部分。

FS=$'\t' read -r NUM STR < <(sed 's#^\([0-9\.]\+[0-9]\+\) \(.*[^0-9]\)$#\1\t\2#p;d' <<< $L )

请帮助我理解我做错了什么。谢谢。

最佳答案

一个 ERE 是:

^([0-9]+(\.[0-9]+)*) (.*[^0-9])$

其中 \1\3 是感兴趣的捕获组

但我不确定使用 sed + read 是捕获变量中数据的最佳方法;你可以只使用 bash 内置函数来代替:

#!/bin/bash

while IFS=' ' read -r num str
do
    [[ $num =~ ^([0-9]+(\.[0-9]+)*)$ && $str =~ [^0-9]$ ]] || continue
    declare -p num str
done < input.txt

不过,此解决方案有一个副作用:read 将删除该行的前导、尾随和第一个中间空格++ 字符。

如果您需要这些空格,那么您可以匹配整行:

#!/bin/bash

regex='^([0-9]+(\.[0-9]+)*) (.*[^0-9])$'

while IFS='' read -r line
do
    [[ $line =~ $regex ]] || continue
    num=${BASH_REMATCH[1]}
    str=${BASH_REMATCH[3]}
    declare -p num str
done < input.txt

关于regex - 将重复的正则表达式模式捕获为一组,在 bash 脚本中使用 sed,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73270483/

相关文章:

regex - 使用 htaccess 将 Paypal 回调重新格式化为自定义 URL 格式

javascript - 使用正则表达式按 id 获取元素

bash - 拆分并推送提交的文件到两个不同的分支

linux - 在 awk 中使用带冒号的 shell 脚本参数

bash - 什么是 shell 变量旁边的连字符

regex - 如何构建文件名的正则表达式,使其不包含特殊字符且长度有限?

regex - 提取电话号码正则表达式

linux - lftp 的记录位置

bash - 如果 grep 找到它要查找的内容,则执行 X else Y

linux - 保存由 wget 下载的图像的多个实例