On Sunday, 8 August 2021 at 23:04:32 UTC, Marcone wrote:
> How to divide by space keeping words with spaces inside quotes?
Exanple:
string text = "Duck Cat "Carl Rivers" Dog";
I want split to:
["Duck", "Cat", "Carl Rivers", "Dog"]
ATENTION: I DON'T WANT:
["Duck", "Cat", "Carl", "Rivers", "Dog"]
How can I get it in Dlang?
regex:
// test with: dmd -unittest -main -run filename.d
string[] splitquote(string s) {
import std.regex : matchAll, regex;
import std.array : array;
import std.algorithm : map;
return s.matchAll(regex(`"([\w ]+)"|(\w+)`)).map!"a[2] ? a[2] : a[1]".array;
}
unittest {
assert(`Duck Cat Carl`.splitquote == ["Duck", "Cat", "Carl"]);
assert(`Duck "Cat" Carl`.splitquote == ["Duck", "Cat", "Carl"]);
assert(`Duck "Cat Carl"`.splitquote == ["Duck", "Cat Carl"]);
assert(`"Duck" "Cat Carl`.splitquote == ["Duck", "Cat", "Carl"]); // GIGO
assert(`"Duck Cat" "Carl"`.splitquote == ["Duck Cat", "Carl"]);
}
PEG:
/++ dub.sdl:
dependency "pegged" version="~>0.4.5"
+/
// test with: dub run -bunittest --single filename.d
import pegged.grammar;
mixin(grammar(q"PEG
Quotable:
Words < (' '* (Quoted/Unquoted))*
Quoted <~ :doublequote (!doublequote .)+ :doublequote
Unquoted < identifier+
PEG"));
string[] splitquote(string s) {
return Quotable(s).matches;
}
unittest {
assert(`Duck Cat Carl`.splitquote == ["Duck", "Cat", "Carl"]);
assert(`Duck "Cat" Carl`.splitquote == ["Duck", "Cat", "Carl"]);
assert(`Duck "Cat Carl"`.splitquote == ["Duck", "Cat Carl"]);
assert(`"Duck" "Cat Carl`.splitquote == ["Duck"]);
assert(`"Duck Cat" "Carl"`.splitquote == ["Duck Cat", "Carl"]);
}
void main() { }