我需要在长字符串中删除在单引号内的模式' - '的所有出现(保留完整的单引号之外的单引号)。
是否有正则表达方式这样做? (使用语言中的迭代器就可以了。)
例如,从
开始"xxxx rt / $ 'dfdf--fggh-dfgdfg' ghgh- dddd -- 'dfdf' ghh-g '--ggh--' vcbcvb"
我最终应该:
"xxxx rt / $ 'dfdffggh-dfgdfg' ghgh- dddd -- 'dfdf' ghh-g 'ggh' vcbcvb"
所以我正在寻找可以从以下语言运行的正则表达式,如图所示
答案 0 :(得分:2)
使用正则表达式无法做到这一点,因为您需要维护状态,无论您是在单引号内还是外部,并且正则表达式本质上是无状态的。 (另外,据我所知,单引号可以在不终止“内部”区域的情况下进行转义。)
你最好的选择是按字符迭代字符串,在你是否在引用区域内保留一个布尔标志 - 然后删除 - 那样。
答案 1 :(得分:2)
我发现另一种方法是通过 Greg Hewgill 在Qn138522的回答中做到这一点 它基于使用这个正则表达式(适合包含我正在寻找的模式):
--(?=[^\']*'([^']|'[^']*')*$)
Greg解释道:
“这样做是使用非捕获匹配
(?=...)
来检查字符x是否在引用的字符串中。它查找一些非引用字符直到下一个引用,然后查找任一序列单个字符或引用的字符组,直到字符串结尾。这取决于你的假设,即引号总是平衡的。这也不是很有效。“
用法示例如下:
input.replace(/--(?=[^']*'([^']|'[^']*')*$)/g, "")
preg_replace('/--(?=[^\']*'([^']|'[^']*')*$)/', "", input)
re.sub(r'--(?=[^\']*'([^']|'[^']*')*$)', "", input)
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。
请注意,此脚本会将'----'转换为'',因为它是一个两个序列 - 在引号内。但是,'---'将转换为' - '。
老学校不是没有学校。