正则表达式:如何只匹配模式一次?
Regex: How to match pattern only once?
我正在尝试从 .config 文件(使用 kconfig 生成)中提取数据。
默认格式为:
SYMBOL=y (in case of a bool)
SYMBOL="str" (in case of a string)
我确实设法让它与以下正则表达式一起工作:
sed -e '/^#/d;s/\(.+\)=\(.+\)/def ""\n/g' configfile > formattedfile
它适用于除此以外的任何情况:
SYMBOL="http://my.domain/toast?id=150"
因此,我的输出文件中有:
def SYMBOL="http://my.domain/toast?id "SYMBOL="http://my.domain/toast?id="
因为模式 XXX=XXX 在这一行中出现了两次。
请问我怎样才能避免这种情况?
此致,
只需在您的命令中删除 g
:
sed -e '/^#/d;s/\(.+\)=\(.+\)/def ""\n/'
^
而不是
sed -e '/^#/d;s/\(.+\)=\(.+\)/def ""\n/g'
^
来自info sed
:
`g'
Apply the replacement to _all_ matches to the REGEXP, not just the
first.
再看一个例子:
$ echo "hello" | sed 's/l/X/' #without g
heXlo
$ echo "hello" | sed 's/l/X/g' #with g
heXXo
您需要转义 +
符号并将第一个 .+
转换为 [^=]\+
因为 .+
是贪婪的并且匹配到最后一个 =
符号。
$ sed -e '/^#/d;s/\([^=]\+\)=\(.\+\)/def ""\n/g' file
def SYMBOL "SYMBOL"
def SYMBOL "SYMBOL"
def SYMBOL "SYMBOL"
问题是 .+
是 greedy:它尝试匹配可能的最长字符串。这延伸到第二个 =
。由于标识符不能包含 =
字符,因此最好在匹配第一部分时更加具体:
sed -e '/^#/d;s/^\([^=]*\)=\(.*\)/def \n/' configfile > formattedfile
请注意,我将第二个 </code> 更改为 <code>
,因为我认为这就是您的意思。我还避免使用扩展正则表达式量词 +
,转而使用更便携的基本正则表达式量词 *
。
我正在尝试从 .config 文件(使用 kconfig 生成)中提取数据。 默认格式为:
SYMBOL=y (in case of a bool)
SYMBOL="str" (in case of a string)
我确实设法让它与以下正则表达式一起工作:
sed -e '/^#/d;s/\(.+\)=\(.+\)/def ""\n/g' configfile > formattedfile
它适用于除此以外的任何情况:
SYMBOL="http://my.domain/toast?id=150"
因此,我的输出文件中有:
def SYMBOL="http://my.domain/toast?id "SYMBOL="http://my.domain/toast?id="
因为模式 XXX=XXX 在这一行中出现了两次。 请问我怎样才能避免这种情况?
此致,
只需在您的命令中删除 g
:
sed -e '/^#/d;s/\(.+\)=\(.+\)/def ""\n/'
^
而不是
sed -e '/^#/d;s/\(.+\)=\(.+\)/def ""\n/g'
^
来自info sed
:
`g'
Apply the replacement to _all_ matches to the REGEXP, not just the
first.
再看一个例子:
$ echo "hello" | sed 's/l/X/' #without g
heXlo
$ echo "hello" | sed 's/l/X/g' #with g
heXXo
您需要转义 +
符号并将第一个 .+
转换为 [^=]\+
因为 .+
是贪婪的并且匹配到最后一个 =
符号。
$ sed -e '/^#/d;s/\([^=]\+\)=\(.\+\)/def ""\n/g' file
def SYMBOL "SYMBOL"
def SYMBOL "SYMBOL"
def SYMBOL "SYMBOL"
问题是 .+
是 greedy:它尝试匹配可能的最长字符串。这延伸到第二个 =
。由于标识符不能包含 =
字符,因此最好在匹配第一部分时更加具体:
sed -e '/^#/d;s/^\([^=]*\)=\(.*\)/def \n/' configfile > formattedfile
请注意,我将第二个 </code> 更改为 <code>
,因为我认为这就是您的意思。我还避免使用扩展正则表达式量词 +
,转而使用更便携的基本正则表达式量词 *
。