2

我正在尝试设计一个产生以下两种情况的正则表达式:

foobar_foobar_190412_foobar_foobar.jpg  =>  190412
foobar_20190311_2372_foobar.jpg         =>  20190311

我想出的正则表达式很接近,但我不知道如何让它只输出第一个数字:

.*_(\d+)_(\d*).*                        =>  $1

foobar_foobar_190412_foobar_foobar.jpg  =>  190412
foobar_20190311_2372_foobar.jpg         =>  (no match)

有人有想法吗?

4

4 回答 4

1

使用选项-P(perl regex)和-o(仅匹配):

grep -Po '^\D+\K\d+' file.txt
190412
20190311

解释:

^           # beginning of line
  \D+       # 1 or more non digit, you can use \D* for 0 or more non digits
  \K        # forget all we have seen until this position
  \d+       # 1 or more digits

根据对grep标签的误解进行编辑

你可以做:

  • 寻找:^\D(\d+)_.*$
  • 代替:$1
于 2019-06-04T16:30:49.187 回答
0

如果你关心下划线匹配,这里有一个sed版本

sed -E 's/[^0-9]*_([0-9]+)_.*/\1/' file
于 2019-06-04T16:46:23.657 回答
0

这就是我一直在寻找的:

find:    \D+_(\d+)_.*
replace: $1

我不知道“非数字”字符!

于 2019-06-04T16:48:00.283 回答
-1

如果我们希望捕获第一个数字,我们可以使用这个简单的表达式:

_([0-9]+)?_

演示

或者

.+?_([0-9]+)?_.+

演示

并将其替换为$1.

正则表达式电路

jex.im可视化正则表达式:

在此处输入图像描述

演示

这个片段只是展示了捕获组是如何工作的:

const regex = /_([0-9]+)?_/gm;
const str = `foobar_foobar_190412_foobar_foobar.jpg
foobar_20190311_2372_foobar.jpg`;
let m;

while ((m = regex.exec(str)) !== null) {
    // This is necessary to avoid infinite loops with zero-width matches
    if (m.index === regex.lastIndex) {
        regex.lastIndex++;
    }
    
    // The result can be accessed through the `m`-variable.
    m.forEach((match, groupIndex) => {
        console.log(`Found match, group ${groupIndex}: ${match}`);
    });
}

于 2019-06-04T16:22:04.593 回答