使用 non_greedy 模式更改括号内的字符串

使用 non_greedy 模式更改括号内的字符串

我正在尝试更改其中的字符串(),并遵循非贪婪模式。

输入:

this is 1(the house owner 2(pet-name john james) john and his friend 3(unknown name james) james fred)

输出:

this is 1(the house owner 2(pet-name xxx-john xxx-james) john and his friend 3(unknown name xxx-james) james fred).

仅在最小范围内的名称才与非贪婪模式()匹配john或替换。james

我尝试使用 perl,但未能获得所需的输出。

答案1

如果您处理的字符串与示例输入和输出一样简单,我会说您把这件事弄得比实际更难。您可以搜索“john)”和“james)”,如下所示:

$ echo "this is 1(the house owner 2(pet-name john) john and his friend 3(unknown name james) james fred)" | sed -r 's/(john\)|james\))/xxx-\1/g'
this is 1(the house owner 2(pet-name xxx-john) john and his friend 3(unknown name xxx-james) james fred)

既然您提到了非贪婪模式,我觉得这其中还有更多内容,而不是您的示例所展示的内容。因此,让我们假装不知道名称后面是否会有一个右括号:

$ echo "this is 1(the house owner 2(pet-name john ok) john and his friend 3(unknown name james test) james fred)" | sed -r 's/(\([^()]*)(john|james)([^()]*\))/\1xxx-\2\3/g'
this is 1(the house owner 2(pet-name xxx-john ok) john and his friend 3(unknown name xxx-james test) james fred)

第一组括号捕获文字左括号之后(包括)的所有内容这不是左括号或右括号直到遇到“james”或者“john”。

第二组括号捕获“john”或“james”。

第三组括号捕获“james”或“john”之后的所有内容这不是左括号或右括号直到遇到文字右括号。

这是一个全局替换,因此无论你有多少组括号,它都会起作用。你甚至可以嵌套更深的括号,这只适用于最小的括号组。

在这种情况下,贪婪不会发挥作用,但如果它对您正在进行的项目起作用,只需添加一个问号(例如 * 变成 *?)以使其非贪婪。

相关内容