我正在尝试创建一个正则表达式来匹配 6 或 7 位长的数字字符串。
[0-9]{6,7} 这可行,但我不希望匹配长度超过 7 位数字的字符串。
请参阅下面的示例数据,其中我需要匹配的粗体数字。一些 6-7 位字符串的开头和结尾有各种字符(换行符、制表符、空格),我也不想匹配开头有两个或多个 0 的字符串。
1139055_00000000000000.jpg1139065_00000000000000.jpg
12345678 1045977_00000000000000.jpg
_1162679.jpg ID:1099695_20230615142941.jpg 1099692_20230615142939.jpg 1162700_00000000000000.jpg 012456.psd 标题:0582457_00_CC 0123456789 标题:6844393_50_v2 标题:6844393_50_v2.psd 0001456789 0000001546800000
总数:14 6582457_00_C 5142090_00_c ID:1178287标题:6582457_00_CC 标题:6844393_50_v2 ID:1178288标题:_0042090_00_cc __6771292_00_cc
输入示例:
1139055_00000000000000.jpg 1139065_00000000000000.jpg
12345678 1045977_00000000000000.jpg
_1162679.jpg ID:1099695_20230615142941.jpg 1099692_20230615142939.jpg 1162700_00000000000000.jpg 012456.psd Title: 0582457_00_CC 0123456789 Title: 6844393_50_v2 Title: 6844393_50_v2.psd 0001456789 0000001546800000
Total: 14 6582457_00_C 5142090_00_c Id: 1178287 Title: 6582457_00_CC Title: 6844393_50_v2 Id: 1178288 Title: _0042090_00_cc __6771292_00_cc
预期输出:
1139055
1139065
1045977
1162679
1099695
1099692
1162700
012456
0582457
6844393
6844393
6582457
5142090
1178287
6582457
6844393
1178288
6771292
任何帮助表示赞赏。
答案1
所以,总而言之,你想要匹配二小数位,其中至少一位必须非零,后跟另一位四五个十进制数字,前面或后面没有其他数字?
如果是这样,请在 PCRE 模式下使用 GNU grep 进行查找:
grep -P '(?<!\d)([1-9][0-9]|[0-9][1-9])[0-9]{4,5}(?!\d)'
使用以下命令测试您的输入-o
:
$ grep -Po '(?<!\d)([1-9][0-9]|[0-9][1-9])[0-9]{4,5}(?!\d)' << \EOF
1139055_00000000000000.jpg 1139065_00000000000000.jpg
12345678 1045977_00000000000000.jpg
_1162679.jpg ID:1099695_20230615142941.jpg 1099692_20230615142939.jpg 1162700_00000000000000.jpg 012456.psd Title: 0582457_00_CC 0123456789 Title: 6844393_50_v2 Title: 6844393_50_v2.psd 0001456789 0000001546800000
Total: 14 6582457_00_C 5142090_00_c Id: 1178287 Title: 6582457_00_CC Title: 6844393_50_v2 Id: 1178288 Title: _0042090_00_cc __6771292_00_cc
EOF
1139055
1139065
1045977
1162679
1099695
1099692
1162700
012456
0582457
6844393
6844393
6582457
5142090
1178287
6582457
6844393
1178288
6771292
答案2
假设您只想要一个简单的解决方案,而不是要求它是单个正则表达式,那么使用 GNU awk (在大多数 Unix 机器上可用或可安装)来处理多字符RS
:
$ awk -v RS='[^0-9]+' '!/^00/ && /^.{6,7}$/' file
1139055
1139065
1045977
1162679
1099695
1099692
1162700
012456
0582457
6844393
6844393
6582457
5142090
1178287
6582457
6844393
1178288
6771292
或者在每个 Unix 机器上的任何 shell 中使用任何 awk,你可以这样做:
awk -F'[^0-9]+' '{ for (i=1; i<=NF; i++) if ( ($i !~ /^00/) && (length($i) ~ /^[67]$/) ) print $i }' file
另外,对于任何用于正则表达式间隔表示法的 POSIX awk(我相信包括 MacOS 上的 BSD awk){6,7}
,您可以使用前面对 awk 的调用将所有非数字字符串转换为换行符,以便默认值RS
随后生效:
awk '{gsub(/[^0-9]+/,RS)} 1' file | awk '!/^00/ && /^.{6,7}$/'
或者,再次使用任何 awk:
awk '{gsub(/[^0-9]+/,RS)} 1' file | awk '!/^00/ && (length() ~ /^[67]$/)'
如果您愿意并且可以在您使用的版本中使用,您可以使用tr -cs '0-9' '\n' < file
或 类似的代替。awk '{gsub(/[^0-9]+/,RS)} 1' file
tr
答案3
grep、sed 和 awk 链提供了您需要的列表:
$ egrep '[0-9]*' -o Q768182 | sed '/00/d' | awk 'length>5 && length <8'
1139055
1139065
1045977
1162679
1099695
1099692
012456
0582457
6844393
6844393
6582457
5142090
1178287
6582457
6844393
1178288
6771292
答案4
这个正则表达式似乎可以为您的示例完成工作:
(?:[^0-9]|^)((?:0[1-9]|[1-9]0|[1-9]{2})[0-9]{4,5})(?:[^0-9]|$)
(?:[^0-9]|^)
:确保其行首或前面的字符不是数字((?:0[1-9]|[1-9]0|[1-9]{2})[0-9]{4,5})
:获取开头不带00的6-7位数字(?:[^0-9]|$)
:确保行尾或后面的字符不是数字
你可以用它来玩https://regex101.com/r/scZc9q/1
由于第一个/最后一个字符将位于匹配的字符串中,因此最简单的使用方法grep
是使用以下命令删除这些字符sed
:
grep -oE '([^0-9]|^)(0[1-9]|[1-9]0|[1-9]{2})[0-9]{4,5}([^0-9]|$)' tmp | sed 's/[^0-9]//g'