Reputation: 341
Currently I'm using replace(/\s*([,.!?:;])[,.!?:;]*\s*/g, '$1 ')
to add space after punctuation. But it doesn't work if the sentence contains three dots.
Example text: "Hello,today is a beautiful day...But tomorrow is,not."
Expected output: "Hello, today is a beautiful day... But tomorrow is, not."
let text = "Hello,today is a beautiful day...But tomorrow is,not.";
text = text.replace(/\s*([,.!?:;])[,.!?:;]*\s*/g, '$1 ')
Gives: "Hello, today is a beautiful day. But tomorrow is, not. "
Please tell me what regex I can use so that I can get the expected output.
Upvotes: 4
Views: 1298
Reputation: 205
Thanks @Wiktor Stribiżew for his suggestions and I come up with the final regex that meets my requirements:
let text = 'Test punctuation:c,c2,c3,d1.D2.D3.Q?.Ec!Sc;Test number:1.200 1,200 2.3.Test:money: $15,000.Test double quote and three dots:I said "Today is a...beautiful,sunny day.".But tomorrow will be a long day...';
text = text.replace(/\.{3,}$|\s*(?:\d[,.]\d|([,.!?:;]+))(?!\s*$)(?!")\s*/g, (m0, m1) => { return m1 ? m1 + ' ' : m0; });
console.log(text); // It will print out: "Test punctuation: c, c2, c3, d1. D2. D3. Q?. Ec! Sc; Test number: 1.200 1,200 2.3. Test: money: $15,000. Test double quote and three dots: I said "Today is a... beautiful, sunny day.". But tomorrow will be a long day..."
Bonus! I also converted this into Dart as I'm using this feature in Flutter app as well. So just in case someone needs to use it in Dart:
void main() {
String addSpaceAfterPunctuation(String words) {
var regExp = r'\.{3,}$|\s*(?:\d[,.]\d|([,.!?:;]+))(?!\s*$)(?!")\s*';
return words.replaceAllMapped(
RegExp(regExp),
(Match m) {
return m[1] != null ? "${m[1]} " : "${m[0]}";
},
);
}
var text = 'Test punctuation:c,c2,c3,d1.D2.D3.Q?.Ec!Sc;Test number:1.200 1,200 2.3.Test:money: \$15,000.Test double quote and three dots:I said "Today is a...beautiful,sunny day.".But tomorrow will be a long day...';
text = addSpaceAfterPunctuation(text);
print(text); // Print out: Test punctuation: c, c2, c3, d1. D2. D3. Q?. Ec! Sc; Test number: 1.200 1,200 2.3. Test: money: $15,000. Test double quote and three dots: I said "Today is a... beautiful, sunny day.". But tomorrow will be a long day...
}
Upvotes: 0
Reputation: 627600
You should match all consecutive punctuation chars into Group 1, not just the first char. Also, it makes sense to exclude a match of the punctuation at the end of the string.
You can use
text.replace(/\s*([,.!?:;]+)(?!\s*$)\s*/g, '$1 ')
Also, it still might be handy to .trim()
the result. See the regex demo.
Details
\s*
- 0 or more whitspace chars([,.!?:;]+)
- Group 1 ($1
): one or more ,
, .
, !
, ?
, :
or ;
(?!\s*$)
- if not immediately followed with zero or more whitespace chars and then end of string\s*
- 0 or more whitspace charsSee a JavaScript demo:
let text = "Hello,today is a beautiful day...But tomorrow is,not.";
text = text.replace(/\s*([,.!?:;]+)(?!\s*$)\s*/g, '$1 ');
console.log(text);
Upvotes: 6