Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/67.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Regex 替换不带双引号的单词_Regex_Sed - Fatal编程技术网

Regex 替换不带双引号的单词

Regex 替换不带双引号的单词,regex,sed,Regex,Sed,我希望unix sed命令只更改不在引号中的basic。[将basic更改为ring] 预期产出: $cat file0 "basic/strong/bold" " /""?basic""/strong/bold" "^/))basic" basic 如果要在位编辑文件,请使用在位选项。如果basic位于行的开头: $> sed -r 's/^([^\"]*)(basic)([^\"]*)$/\1ring\3/' file0 "basic/strong/bold" " /""?basi

我希望unix sed命令只更改不在引号中的basic。[将basic更改为ring]

预期产出:

$cat file0
"basic/strong/bold"
" /""?basic""/strong/bold"
"^/))basic"
basic 

如果要在位编辑文件,请使用在位选项。

如果basic位于行的开头:

$> sed -r 's/^([^\"]*)(basic)([^\"]*)$/\1ring\3/' file0
"basic/strong/bold"
" /""?basic""/strong/bold"
"^/))basic"
ring

如果我们不允许转义引号,那么任何不在其中的basic前面都会有偶数个引号。因此,这应该可以做到:

sed -e 's/^basic/ring/' file0
并且如前所述,添加-in-place选项将立即编辑文件,而不是返回新内容

这是怎么回事

我们将正则表达式锚定到每行的开头。然后我们允许任意数量的带有[^]*的非字符。然后我们开始一个新的子模式[^]*它由一个或任意多个非字符组成。我们用{2}*重复了偶数次。然后我们匹配基本的。因为我们在basic之前匹配了所有这些东西,所以我们也会替换它们。这就是为什么这个部分被另一对括号括起来,从而捕获该行并将其写回替换项中,\1后跟环


一个警告:如果在一行中有多个基本匹配项,这将只替换最后一个没有用双引号括起来的,因为正则表达式匹配项不能重叠。解决方案可能是一个lookbehind,但由于这是一个可变长度的lookbehind,它仅由.NET正则表达式引擎支持。因此,如果在实际输入中是这种情况,请多次运行该命令,直到替换所有出现的内容。

这可能适用于GNU-sed:

sed -r 's/^([^"]*("[^"]*){2}*)basic/\1ring/' file

不是sed解决方案,但它替代了不在引号中的单词

假设字符串中没有转义引号,即这是一个陷阱\hehe,awk可能能够解决这个问题

sed -r 's/^/\n/;ta;:a;s/\n$//;t;s/\n("[^"]*")/\1\n/;ta;s/\nbasic/ring\n/;ta;s/\n([^"]*)/\1\n/;ta' file
基本上,不在引号中的单词位于奇数字段中,在这些字段中,单词basic被ring替换


这可以写为一行,但为了清楚起见,我已经写了多行。

这将只替换根本不包含适合给定示例的基本in行,我承认,但不是问题的描述所以双引号从哪里开始?如果一行只包含“基本”一词,你希望发生什么?是否应更改为“环形”或不更改?
sed -r 's/^/\n/;ta;:a;s/\n$//;t;s/\n("[^"]*")/\1\n/;ta;s/\nbasic/ring\n/;ta;s/\n([^"]*)/\1\n/;ta' file
awk -F\" 'BEGIN {OFS=FS} 
          { 
            for(i=1; i<=NF; i++){
              if(i%2)
                gsub(/basic/,"ring",$i)
            }
            print
          }' inputFile