How to replace inside regex?
Ali Çehreli via Digitalmars-d-learn
digitalmars-d-learn at puremagic.com
Thu Dec 17 09:32:33 PST 2015
On 12/17/2015 04:57 AM, Suliman wrote:
> find all commas in strings inside quotes and replace them.
>
> foo, bar, "hello, user", baz
[...]
> auto partWithComma = matchAll(line, r).replaceAll(",", " ");
For this particular case, do you really want to replace with spaces, or
do you want to eliminate them?
1) If the latter, I am sure you already know that you can call filter on
the whole string:
import std.algorithm;
void main() {
auto s = `foo, bar, "hello, user", baz`;
auto result = s.filter!(c => c != '"');
assert(result.equal(`foo, bar, hello, user, baz`));
}
Note that 'result' above is a range that is produced lazily. If you need
the result to be a proper array, then append a .array at the end (but
don't forget to import std.array or std.range in that case):
import std.array;
auto result = s.filter!(c => c != '"').array;
Now 'result' in an array.
2) Also consider std.array.replace:
http://dlang.org/phobos/std_array.html#.replace
3) For your general question about regular expressions, there may be
other solutions but the following style works for me:
import std.stdio;
import std.string;
import std.regex;
import std.array;
void main() {
auto data = [ "abc=1", "def=2", "xyz=3" ];
/* Matches patterns like a=1
*
* Note the parentheses around the two patterns. Those parentheses
allow
* us to refer to the matched parts with indexes 1, 2, etc. later.
*/
enum re = regex(`([a-z]*)=([0-9]*)`);
foreach (line; data) {
if (matchFirst(line, re)) {
/* This line matched. */
/* Instead of such a "sink" delegate, you can use
std.appender to
* collect the replaced lines. This one makes use of the
* replacement right away by sending it to standard output.
*/
auto useTheLine = (const(char)[] replaced) {
if (replaced.empty) {
/* QUESTION TO OTHERS: Why is this function called with
* empty strings twice, apparently before and after
each
* actual replacement? Is that intentional? */
} else {
// This is where we actually use the replacement
writeln(replaced);
}
};
replaceAllInto!makeReplacement(useTheLine, line, re);
}
}
}
string makeReplacement(Captures!(string) matched) {
// Note: matched[0] would be the whole matched line
const label = matched[1];
const value = matched[2];
// We produce the new string here:
return format("((%s)) ((%s))", label, value);
}
Ali
More information about the Digitalmars-d-learn
mailing list