如果不在前面或后面跟有相同的字符,则替换字符

时间:2016-11-16 10:55:26

标签: javascript regex

我试图用两个连续的引号替换字符串中的非连续单引号。

示例(进/出)

  • "abc'def" - > "abc''def"
  • "abc''de'f" - > "abc''de''f"

Javascript不支持lookbehinds,因此以下使用Java(或多或少)的正则表达式将编译:

myString.replace(/(?<!)'(?!'))/g, "''");

我已经环顾四周了,一些答案建议使用一个非捕获组,其中包含一个自定义角色类,否定了否则将会出现在负面的背后的角色:

myString.replace(/(?:[^'])'(?!'))/g, "''");

然而,这也不会做:它将成功地不会替换两个连续的单引号,但在"abc''de'f"示例中,它将&#34; eat&#34;用两个连续的单引号替换下一个单引号时的f,最后是:

"abc''de''gh"(看到它错过了f!)

问题

  • 是否有适合此问题的基于正则表达式的解决方案?
  • 如果没有,我是否应该进行野蛮的迭代并索引所有输入字符串的字符并痛苦地从中构建另一个字符串(请不要)?

5 个答案:

答案 0 :(得分:2)

您可以使用此正则表达式:

str = str.replace(/(^|[^'])'(?!')/g, "$1''"));
  • 它匹配单引号前的行开头或非单引号字符,并在#1组中捕获它。
  • 使用否定前瞻它还断言匹配的单引号后面没有其他单引号。
  • 在替换中,我们使用捕获的组#1和两个''
  • 的反向引用

完整代码:

var arr = ["abc'def", "abc''de'f"];

for (i=0; i<arr.length; i++) {
   console.log( arr[i] + ' => ' + arr[i].replace(/(^|[^'])'(?!')/g, "$1''") );
}

<强>输出:

abc'def => ab''def
abc''de'f => abc''d''f

答案 1 :(得分:2)

您还可以将2个或更多个单撇号匹配到捕获组中,并匹配所有其他单个撇号,并在任一情况下使用回调来使用正确的替换:

&#13;
&#13;
var ss = ["abc'def" , "abc''de'f", "abc''''''def'g"];
for (var s of ss) {
  console.log(s.replace(/('{2,})|'/g, function($0,$1) { return $1 ? $1 : "''"; }));
}
&#13;
&#13;
&#13;

此解决方案不会将'''''缩减为'' replace(/'+/g, "''")

详细

  • ('{2,}) - 匹配并捕获到组1中两次或更多次出现'
  • | - 或
  • ' - 单个撇号在所有其他上下文中匹配。

回调方法接受$0(整个匹配)和$1(组1)。如果$1未定义,则会重新插入其值,否则'(整个匹配)将替换为''

答案 2 :(得分:1)

谦卑的链条取代怎么样?

&#13;
&#13;
str = "abc'def --> abc''def abc''de'f --> abc''de''f"
console.log(str)
console.log(str.replace(/''/g,"|").replace(/'/g,"''").replace(/\|/g,"''"))
&#13;
&#13;
&#13;

答案 3 :(得分:1)

由于多个(=超过2个)引号对您来说不是问题,如果在给定位置有一个或两个引号,您实际上不需要太在意,只是 - 所以只需替换每个出现引用双引号的引号。正则表达式为/'+/g,可以替换为"''"

答案 4 :(得分:0)

我在这个正则表达式上取得了成功:

/([^\'])\'([^\'])/g

示例:

&#13;
&#13;
var afterRegex = document.getElementsByClassName('after')[0];
var listItems = afterRegex.getElementsByTagName('li');

for (var i = 0; i < listItems.length; i++) {

var string = listItems[i].textContent;
var convertedString = string.replace(/([^\'])\'([^\'])/g, "$1''$2");
listItems[i].textContent = convertedString;

}
&#13;
div {
float: left;
width: 200px;
}
&#13;
<div>
<h2>Before:</h2>
<ul class="before">
<li>"abc'def"</li>
<li>"abc''de'f"</li>
</ul>
</div>

<div>
<h2>After:</h2>
<ul class="after">
<li>"abc'def"</li>
<li>"abc''de'f"</li>
</ul>
</div>
&#13;
&#13;
&#13;