使用终端中的RegEx从字符串中提取字符串

fre*_*nte 40 regex bash grep

我有一个类似的字符串,first url, second url, third url并且只想在OS X终端中提取url单词之后second(仅第一次出现).我该怎么做?

我最喜欢的编辑器中,我使用正则表达式/second (url)/并用于$1提取它,我只是不知道如何在终端中执行它.

请记住,这url是一个实际的网址,我将使用其中一个表达式来匹配它:正则表达式匹配网址

Sjo*_*erd 56

echo 'first url, second url, third url' | sed 's/.*second//'
Run Code Online (Sandbox Code Playgroud)

编辑:我误解了.更好:

echo 'first url, second url, third url' | sed 's/.*second \([^ ]*\).*/\1/'
Run Code Online (Sandbox Code Playgroud)

要么:

echo 'first url, second url, third url' | perl -nle 'm/second ([^ ]*)/; print $1'
Run Code Online (Sandbox Code Playgroud)


Dmi*_*yas 14

管道到另一个进程(如上面建议的'sed'和'perl')可能非常昂贵,尤其是当您需要多次运行此操作时.Bash确实支持regexp:

[["string"=〜regex]]

同样你使用提取您喜欢的编辑器相匹配的方式$1,$2等等,猛砸填充在$BASH_REMATCH所有的比赛阵列.

在您的特定示例中:

str="first usr1, second url2, third url3"
if [[ $str =~ (second )([^,]*) ]]; then echo "match: '${BASH_REMATCH[2]}'"; else echo "no match found"; fi
Run Code Online (Sandbox Code Playgroud)

输出:

match: 'url2'
Run Code Online (Sandbox Code Playgroud)

具体来说,=~支持POSIX定义的扩展正则表达式,但具有特定平台的扩展(扩展程度不同且可能不兼容). 在Linux平台(GNU userland)上,请参阅; 在macOS/BSD平台上,请参阅.
man grepman re_format

  • @akauppi,启动一个新进程需要付出代价(操作系统必须分配很多东西,运行一些检查,设置环境,执行一些磁盘IO,切换上下文等等.然后在完成外部进程后,需要进行一些额外的清理工作.好).为简单起见,让我们进 我们将处理14,000行CSV ascii文件.使用"bash支持正则表达式"需要1秒钟!如果我迭代行并为每行调用"sed",则需要42秒.我需要处理1.4M行,所以它会成功:100秒"bash方式"vs 1小时10分钟管道到"sed"!感到不同!(C) :) (3认同)

mhi*_*tza 7

在另一个答案中,您仍然可以使用所需的URL后的所有内容.所以我建议您使用以下解决方案.

echo 'first url, second url, third url' | sed 's/.*second \(url\)*.*/\1/'
Run Code Online (Sandbox Code Playgroud)

在sed下,您可以通过绕过它的括号(POSIX标准)对表达式进行分组.


Yet*_*eti 6

在尝试此操作时,您可能忘记-Esed.

来自sed --help

  -E, -r, --regexp-extended
                 use extended regular expressions in the script
                 (for portability use POSIX -E).
Run Code Online (Sandbox Code Playgroud)

您不必显着更改您的正则表达式,但您确实需要添加.*以贪婪地匹配它以删除字符串的另一部分。

这对我来说很好用:

echo "first url, second url, third url" | sed -E 's/.*second (url).*/\1/'
Run Code Online (Sandbox Code Playgroud)

输出:

url
Run Code Online (Sandbox Code Playgroud)

其中输出“url”实际上是字符串中的第二个实例。但是,如果您已经知道它的格式介于逗号和空格之间,并且您不允许在 URL 中使用这些字符,那么正则表达式[^,]*应该没问题。

可选:

echo "first http://test.url/1, second ://test.url/with spaces/2, third ftp://test.url/3" \
     | sed -E 's/.*second ([a-zA-Z]*:\/\/[^,]*).*/\1/'
Run Code Online (Sandbox Code Playgroud)

哪个正确输出:

://example.com/with spaces/2
Run Code Online (Sandbox Code Playgroud)