Skip to content

Commit

Permalink
String.replace: preliminary support for regex patterns
Browse files Browse the repository at this point in the history
  • Loading branch information
thiagoarrais committed Oct 31, 2019
1 parent a540bd7 commit 5643b61
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 8 deletions.
4 changes: 2 additions & 2 deletions src/lib/builtins/regexp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ use crate::{
};

#[derive(Debug)]
struct RegExp {
pub struct RegExp {
/// Regex matcher.
matcher: Regex,
pub matcher: Regex,
/// Update last_index, set if global or sticky flags are set.
use_last_index: bool,
/// String of parsed flags.
Expand Down
22 changes: 16 additions & 6 deletions src/lib/builtins/string.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use crate::{
function::NativeFunctionData,
object::{Object, ObjectKind, PROTOTYPE},
property::Property,
regexp::{make_regexp, match_all as regexp_match_all, r#match as regexp_match},
regexp::{make_regexp, match_all as regexp_match_all, r#match as regexp_match, RegExp},
value::{from_value, to_value, undefined, ResultValue, Value, ValueData},
},
exec::Interpreter,
Expand Down Expand Up @@ -742,12 +742,20 @@ pub fn replace(this: &Value, args: &[Value], ctx: &mut Interpreter) -> ResultVal
return Ok(to_value(this_str));
}
let replacement = get_argument(args, 1);
let pattern_str: &str = &ctx.value_to_rust_string(&pattern);
let replacement_str: &str = &ctx.value_to_rust_string(&replacement);
// The Rust pattern is interpreted as a Regex and replaced in the original string with
// the replacement by using Regex.replace_all
let result_str = this_str.replace(pattern_str, replacement_str);
Ok(to_value(result_str))

if pattern.is_string() {
let pattern_str: &str = &ctx.value_to_rust_string(&pattern);
// The Rust pattern is interpreted as a Regex and replaced in the original string with
// the replacement by using Regex.replace_all
let result_str = this_str.replace(pattern_str, replacement_str);
Ok(to_value(result_str))
} else {
pattern.with_internal_state_ref(|pattern_re: &RegExp| {
let result_str = pattern_re.matcher.replace_all(this_str, replacement_str);
Ok(to_value(result_str.into_owned()))
})
}
}

fn get_argument(args: &[Value], idx: usize) -> Value {
Expand Down Expand Up @@ -1080,13 +1088,15 @@ mod tests {
var str = 'The quick brown fox jumps over the lazy dog. If the dog reacted, was it really lazy?';
var result1 = str.replace('dog', 'monkey');
var result2 = str.replace('dog.', 'monkey.');
var regexResult = str.replace(/dog./, 'monkey.');
var exceptional1 = str.replace();
var exceptional2 = str.replace('dog');
"#;

forward(&mut engine, init);
assert_eq!(forward(&mut engine, "result1"), "The quick brown fox jumps over the lazy monkey. If the monkey reacted, was it really lazy?");
assert_eq!(forward(&mut engine, "result2"), "The quick brown fox jumps over the lazy monkey. If the dog reacted, was it really lazy?");
assert_eq!(forward(&mut engine, "regexResult"), "The quick brown fox jumps over the lazy monkey. If the monkey.reacted, was it really lazy?");
assert_eq!(
forward(&mut engine, "exceptional1"),
"The quick brown fox jumps over the lazy dog. If the dog reacted, was it really lazy?"
Expand Down

0 comments on commit 5643b61

Please sign in to comment.