使用正则表达式调用替换分隔符内的模式

时间:2008-10-07 23:13:46

标签: regex

我需要在长字符串中删除单引号内的模式' - '的所有出现(保留完整的单引号之外的单引号)。

是否有正则表达方式这样做? (使用语言中的迭代器就可以了。)

例如,从

开始
"xxxx rt / $ 'dfdf--fggh-dfgdfg' ghgh- dddd -- 'dfdf' ghh-g '--ggh--' vcbcvb"

我最终应该:

"xxxx rt / $ 'dfdffggh-dfgdfg' ghgh- dddd -- 'dfdf' ghh-g 'ggh' vcbcvb"

所以我正在寻找可以从以下语言运行的正则表达式,如图所示

  • JavaScript input.replace(/ someregex / g,“”)
  • PHP preg_replace('/ someregex /',“”,input)
  • Python re.sub(r'someregex',“”,input)
  • Ruby input.gsub(/ someregex /,“”)

5 个答案:

答案 0 :(得分:2)

使用正则表达式无法做到这一点,因为您需要维护状态,无论您是在单引号内还是外部,并且正则表达式本质上是无状态的。 (另外,据我所知,单引号可以在不终止“内部”区域的情况下进行转义。)

你最好的选择是按字符迭代字符串,在你是否在引用区域内保留一个布尔标志 - 然后删除 - 那样。

答案 1 :(得分:2)

我发现另一种方法是通过 Greg Hewgill Qn138522的回答中做到这一点 它基于使用这个正则表达式(适合包含我正在寻找的模式):

--(?=[^\']*'([^']|'[^']*')*$)

Greg解释道:

  

“这样做是使用非捕获匹配(?=...)来检查字符x是否在引用的字符串中。它查找一些非引用字符直到下一个引用,然后查找任一序列单个字符或引用的字符组,直到字符串结尾。这取决于你的假设,即引号总是平衡的。这也不是很有效。“

用法示例如下:

  • JavaScript:input.replace(/--(?=[^']*'([^']|'[^']*')*$)/g, "")
  • PHP:preg_replace('/--(?=[^\']*'([^']|'[^']*')*$)/', "", input)
  • Python:re.sub(r'--(?=[^\']*'([^']|'[^']*')*$)', "", input)
  • Ruby:input.gsub(/--(?=[^\']*'([^']|'[^']*')*$)/, "")

我已经为Ruby测试了它,它提供了所需的结果。

答案 2 :(得分:1)

如果允许稍微弯曲规则,这可能有效:

import re
p = re.compile(r"((?:^[^']*')?[^']*?(?:'[^']*'[^']*?)*?)(-{2,})")
txt = "xxxx rt / $ 'dfdf--fggh-dfgdfg' ghgh- dddd -- 'dfdf' ghh-g '--ggh--' vcbcvb"
print re.sub(p, r'\1-', txt)

输出:

xxxx rt / $ 'dfdf-fggh-dfgdfg' ghgh- dddd -- 'dfdf' ghh-g '-ggh-' vcbcvb

正则表达式:

(               # Group 1
  (?:^[^']*')?  # Start of string, up till the first single quote
  [^']*?        # Inside the single quotes, as few characters as possible
  (?:
    '[^']*'     # No double dashes inside theses single quotes, jump to the next.
    [^']*?
  )*?           # as few as possible
)
(-{2,})         # The dashes themselves (Group 2)

如果有不同的开始和结束分隔符,您可以使用以下内容:

-{2,}(?=[^'`]*`)

编辑:我意识到如果字符串不包含任何引号,它将匹配字符串中的所有双短划线。修复它的一种方法是改变

(?:^[^']*')?

开头

(?:^[^']*'|(?!^))

更新了正则表达式:

((?:^[^']*'|(?!^))[^']*?(?:'[^']*'[^']*?)*?)(-{2,})

答案 3 :(得分:0)

嗯。如果没有带引号的撇号,可能可能是的一种方式,假设有(?( id / name ) 是-pattern | 无模式 )在正则表达式中构造,但它现在已经过时了。

这有帮助吗?

def remove_double_dashes_in_apostrophes(text):
    return "'".join(
    part.replace("--", "") if (ix&1) else part
    for ix, part in enumerate(text.split("'")))

似乎适合我。它的作用是将输入文本拆分为撇号上的部分,并仅在部分为奇数时替换“ - ”(即在部分之前存在奇数个撇号)。关于“奇数”的注释:部件编号从零开始!

答案 4 :(得分:0)

我相信你可以使用以下sed脚本:

:again
s/'\(.*\)--\(.*\)'/'\1\2'/g
t again

将其存储在一个文件(rmdashdash.sed)中并使用脚本语言执行任何exec magic允许您执行以下shell等效操作:

sed -f rmdotdot.sed<包含输入数据的文件

脚本的作用是:

:again < - 只是一个标签

<强> s/'\(.*\)--\(.*\)'/'\1\2'/g

替换,对于模式'后跟任何后跟 - 后跟任何后跟',只是引号中的两个任何内容。

t again &lt; - 将结果字符串重新输入sed。

请注意,此脚本会将'----'转换为'',因为它是一个两个序列 - 在引号内。但是,'---'将转换为' - '。

老学校不是没有学校。