正则表达式可以用于这种特殊的字符串操作吗?

2024-09-28 03:23:58 发布

您现在位置:Python中文网/ 问答频道 /正文

我需要将字符串中的字符(比如)x替换为字符串中的字符(比如)p,但前提是它包含在带引号的子字符串中。 举例说明:

axbx'cxdxe'fxgh'ixj'k  -> axbx'cPdPe'fxgh'iPj'k

为了简单起见,我们假设引号总是成对出现的。在

显而易见的方法是一次只处理一个字符的字符串(一种简单的状态机方法);
但是,我想知道正则表达式是否可以一次性完成所有处理。在

我的目标语言是C,但我想我的问题与任何支持正则表达式的内置或库语言有关。在


Tags: 方法字符串语言字符内置引号状态机前提
3条回答

诀窍是使用非捕获组匹配字符串后面的部分(characterx)。 尝试将字符串匹配到x只会找到第一个或最后一个出现,这取决于是否使用了非贪婪量词。 以下是Greg的想法,并附上评论。在

set strIn {axbx'cxdxe'fxgh'ixj'k}
set regex {(?x)                     # enable expanded syntax 
                                    # - allows comments, ignores whitespace
            x                       # the actual match
            (?=                     # non-matching group
                [^']*'              # match to end of current quoted substring
                                    ##
                                    ## assuming quotes are in pairs,
                                    ## make sure we actually were 
                                    ## inside a quoted substring
                                    ## by making sure the rest of the string 
                                    ## is what we expect it to be
                                    ##
                (
                    [^']*           # match any non-quoted substring
                    |               # ...or...
                    '[^']*'         # any quoted substring, including the quotes
                )*                  # any number of times
                $                   # until we run out of string :)
            )                       # end of non-matching group
}

#the same regular expression without the comments
set regexCondensed {(?x)x(?=[^']*'([^']|'[^']*')*$)}

set replRegex {P}
set nMatches [regsub -all -- $regex $strIn $replRegex strOut]
puts "$nMatches replacements. "
if {$nMatches > 0} {
    puts "Original: |$strIn|"
    puts "Result:   |$strOut|"
}
exit

打印:

^{pr2}$

把它转换成了python的代码!在

[Test]
public void ReplaceTextInQuotes()
{
  Assert.AreEqual("axbx'cPdPe'fxgh'iPj'k", 
    Regex.Replace("axbx'cxdxe'fxgh'ixj'k",
      @"x(?=[^']*'([^']|'[^']*')*$)", "P"));
}

那个测试通过了。在

我可以用Python做到这一点:

>>> import re
>>> re.sub(r"x(?=[^']*'([^']|'[^']*')*$)", "P", "axbx'cxdxe'fxgh'ixj'k")
"axbx'cPdPe'fxgh'iPj'k"

这样做的是使用非捕获匹配(?)?=…)以检查字符x是否在带引号的字符串中。它查找一些直到下一个引号的非引号字符,然后查找单个字符或带引号的字符组的序列,直到字符串的结尾。在

这取决于你的假设,即报价总是平衡的。这也不是很有效。在

相关问题 更多 >

    热门问题