added ability to opt in to normal string replacement in replace
cmd (#5133)
* added ability to opt in to normal string replacement in `replace` cmd * type-o
This commit is contained in:
parent
7ce570e52c
commit
74d0f19291
|
@ -13,6 +13,7 @@ struct Arguments {
|
||||||
replace: String,
|
replace: String,
|
||||||
column_paths: Vec<CellPath>,
|
column_paths: Vec<CellPath>,
|
||||||
literal_replace: bool,
|
literal_replace: bool,
|
||||||
|
no_regex: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
|
@ -38,6 +39,11 @@ impl Command for SubCommand {
|
||||||
"do not expand the replace parameter as a regular expression",
|
"do not expand the replace parameter as a regular expression",
|
||||||
Some('n'),
|
Some('n'),
|
||||||
)
|
)
|
||||||
|
.switch(
|
||||||
|
"string",
|
||||||
|
"do not use regular expressions for string find and replace",
|
||||||
|
Some('s'),
|
||||||
|
)
|
||||||
.category(Category::Strings)
|
.category(Category::Strings)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,7 +113,22 @@ impl Command for SubCommand {
|
||||||
span: Span::test_data(),
|
span: Span::test_data(),
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
|
Example {
|
||||||
|
description: "Find and replace the first occurence using string replacement *not* regular expressions",
|
||||||
|
example: r#"'c:\some\cool\path' | str replace 'c:\some\cool' '~' -s"#,
|
||||||
|
result: Some(Value::String {
|
||||||
|
val: "~\\path".to_string(),
|
||||||
|
span: Span::test_data(),
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
Example {
|
||||||
|
description: "Find and replace all occurences using string replacement *not* regular expressions",
|
||||||
|
example: r#"'abc abc abc' | str replace -a 'b' 'z' -s"#,
|
||||||
|
result: Some(Value::String {
|
||||||
|
val: "azc azc azc".to_string(),
|
||||||
|
span: Span::test_data(),
|
||||||
|
}),
|
||||||
|
},
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -118,9 +139,11 @@ fn operate(
|
||||||
call: &Call,
|
call: &Call,
|
||||||
input: PipelineData,
|
input: PipelineData,
|
||||||
) -> Result<PipelineData, ShellError> {
|
) -> Result<PipelineData, ShellError> {
|
||||||
|
let head = call.head;
|
||||||
let find: Spanned<String> = call.req(engine_state, stack, 0)?;
|
let find: Spanned<String> = call.req(engine_state, stack, 0)?;
|
||||||
let replace: Spanned<String> = call.req(engine_state, stack, 1)?;
|
let replace: Spanned<String> = call.req(engine_state, stack, 1)?;
|
||||||
let literal_replace = call.has_flag("no-expand");
|
let literal_replace = call.has_flag("no-expand");
|
||||||
|
let no_regex = call.has_flag("string");
|
||||||
|
|
||||||
let options = Arc::new(Arguments {
|
let options = Arc::new(Arguments {
|
||||||
all: call.has_flag("all"),
|
all: call.has_flag("all"),
|
||||||
|
@ -128,8 +151,9 @@ fn operate(
|
||||||
replace: replace.item,
|
replace: replace.item,
|
||||||
column_paths: call.rest(engine_state, stack, 2)?,
|
column_paths: call.rest(engine_state, stack, 2)?,
|
||||||
literal_replace,
|
literal_replace,
|
||||||
|
no_regex,
|
||||||
});
|
});
|
||||||
let head = call.head;
|
|
||||||
input.map(
|
input.map(
|
||||||
move |v| {
|
move |v| {
|
||||||
if options.column_paths.is_empty() {
|
if options.column_paths.is_empty() {
|
||||||
|
@ -162,6 +186,7 @@ fn action(
|
||||||
replace,
|
replace,
|
||||||
all,
|
all,
|
||||||
literal_replace,
|
literal_replace,
|
||||||
|
no_regex,
|
||||||
..
|
..
|
||||||
}: &Arguments,
|
}: &Arguments,
|
||||||
head: Span,
|
head: Span,
|
||||||
|
@ -169,6 +194,21 @@ fn action(
|
||||||
match input {
|
match input {
|
||||||
Value::String { val, .. } => {
|
Value::String { val, .. } => {
|
||||||
let FindReplace(find, replacement) = FindReplace(find, replace);
|
let FindReplace(find, replacement) = FindReplace(find, replace);
|
||||||
|
if *no_regex {
|
||||||
|
// just use regular string replacement vs regular expressions
|
||||||
|
if *all {
|
||||||
|
Value::String {
|
||||||
|
val: val.replace(find, replacement),
|
||||||
|
span: head,
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Value::String {
|
||||||
|
val: val.replacen(find, replacement, 1),
|
||||||
|
span: head,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// use regular expressions to replace strings
|
||||||
let regex = Regex::new(find);
|
let regex = Regex::new(find);
|
||||||
|
|
||||||
match regex {
|
match regex {
|
||||||
|
@ -203,6 +243,7 @@ fn action(
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
other => Value::Error {
|
other => Value::Error {
|
||||||
error: ShellError::UnsupportedInput(
|
error: ShellError::UnsupportedInput(
|
||||||
format!(
|
format!(
|
||||||
|
@ -240,6 +281,7 @@ mod tests {
|
||||||
column_paths: vec![],
|
column_paths: vec![],
|
||||||
literal_replace: false,
|
literal_replace: false,
|
||||||
all: false,
|
all: false,
|
||||||
|
no_regex: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
let actual = action(&word, &options, Span::test_data());
|
let actual = action(&word, &options, Span::test_data());
|
||||||
|
|
Loading…
Reference in New Issue
Block a user