admin 管理员组文章数量: 1086019
I am trying to replace non-consecutive single quotes in a string with two consecutive quotes.
Examples (in/out)
"abc'def"
-->"abc''def"
"abc''de'f"
-->"abc''de''f"
- etc.
Javascript doesn't support lookbehinds, so the following regular expression I'd use with Java (well, more or less) will not pile:
myString.replace(/(?<!)'(?!'))/g, "''");
I have looked around SO and some answers advise using a non-capturing group containing a custom character class negating the character that would otherwise be in the negative lookbehind:
myString.replace(/(?:[^'])'(?!'))/g, "''");
However, that will not do either: it will successfully not replace the two consecutive single quotes, but in the "abc''de'f"
example, it will "eat" the f
when replacing the next single quote with two consecutive single quotes, ending up in:
"abc''de''gh"
(see it's missing the f
!)
Questions
- Is there a suitable regex-based solution for this problem?
- If not, should I just go with a barbaric iteration and indexing of all the input string's characters and painfully build another string from it (please no)?
I am trying to replace non-consecutive single quotes in a string with two consecutive quotes.
Examples (in/out)
"abc'def"
-->"abc''def"
"abc''de'f"
-->"abc''de''f"
- etc.
Javascript doesn't support lookbehinds, so the following regular expression I'd use with Java (well, more or less) will not pile:
myString.replace(/(?<!)'(?!'))/g, "''");
I have looked around SO and some answers advise using a non-capturing group containing a custom character class negating the character that would otherwise be in the negative lookbehind:
myString.replace(/(?:[^'])'(?!'))/g, "''");
However, that will not do either: it will successfully not replace the two consecutive single quotes, but in the "abc''de'f"
example, it will "eat" the f
when replacing the next single quote with two consecutive single quotes, ending up in:
"abc''de''gh"
(see it's missing the f
!)
Questions
- Is there a suitable regex-based solution for this problem?
- If not, should I just go with a barbaric iteration and indexing of all the input string's characters and painfully build another string from it (please no)?
-
1
How would you handle triple quotes? Are they an issue? If not match
'+
and replace with''
– Sebastian Proske Commented Nov 16, 2016 at 10:57 - @SebastianProske that is actually working for me, triple quotes can be ignored in my use case. Can I invite you to put this into an answer - unless there's a duplicate I haven't found? – Mena Commented Nov 16, 2016 at 11:00
- Thanks all for answering. I'm accepting Sebastian's answer because it is the simplest in my use case, but I can see the merit in the other answers, especially anubhava's for the cool lookbehind "workaround" and Wiktor's for the powerful callback idiom. – Mena Commented Nov 16, 2016 at 11:23
5 Answers
Reset to default 3You can use this regex:
str = str.replace(/(^|[^'])'(?!')/g, "$1''"));
- It matches line start or non single quote character before a single quote and captures it in a group #1.
- Using a negative lookahead it also asserts that matched single quote is not followed by another single quote.
- In replacement we use back-reference of captured group #1 and two
''
Full code:
var arr = ["abc'def", "abc''de'f"];
for (i=0; i<arr.length; i++) {
console.log( arr[i] + ' => ' + arr[i].replace(/(^|[^'])'(?!')/g, "$1''") );
}
Output:
abc'def => ab''def
abc''de'f => abc''d''f
You may also match 2 or more occurrences of single apostrophes into a capturing group and just match all other single apostrophes, and use a callback to use the right replacement in either cases:
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 : "''"; }));
}
This solution won't shrink '''''
to ''
as replace(/'+/g, "''")
would.
Details:
('{2,})
- matches and captures into Group 1 two or more occurrences of'
|
- or'
- a single apostrophe is matched in all other contexts.
The callback method accepts $0
(the whole match) and $1
(Group 1). If $1
is not undefined, then its value is reinserted, else '
(the whole match) is replaced with ''
.
As multiple (=more than 2) quotes are not an issue for you, you don't actually need to take that much care, if there are one or two quotes at a given place, just - so just replace every occurence of quotes with the wanted double quotes. The regex for this would be /'+/g
and can be replaced by "''"
How about the humble chained replace?
str = "abc'def --> abc''def abc''de'f --> abc''de''f"
console.log(str)
console.log(str.replace(/''/g,"|").replace(/'/g,"''").replace(/\|/g,"''"))
I had success with this regular expression:
/([^\'])\'([^\'])/g
Example:
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;
}
div {
float: left;
width: 200px;
}
<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>
本文标签: javascriptReplace character if not preceded nor followed by same characterStack Overflow
版权声明:本文标题:javascript - Replace character if not preceded nor followed by same character - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://roclinux.cn/p/1744084397a2530849.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论