Skip to content

Commit c955d2f

Browse files
committed
Add 'Regex Replace'
1 parent 949be06 commit c955d2f

File tree

4 files changed

+55
-4
lines changed

4 files changed

+55
-4
lines changed

Cargo.lock

Lines changed: 16 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ bitflags = { version = "2.4", features = ["serde"] }
107107
ctor = "0.2"
108108
convert_case = "0.8"
109109
titlecase = "3.6"
110+
fancy-regex = "0.17"
110111
unicode-segmentation = "1.13.2"
111112
indoc = "2.0.5"
112113
derivative = "2.2"

node-graph/nodes/gcore/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ log = { workspace = true }
3030
serde_json = { workspace = true }
3131
convert_case = { workspace = true }
3232
titlecase = { workspace = true }
33+
fancy-regex = { workspace = true }
3334
unicode-segmentation = { workspace = true }
3435

3536
# Optional workspace dependencies

node-graph/nodes/gcore/src/logic.rs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -587,6 +587,43 @@ async fn switch<T, C: Send + 'n + Clone>(
587587
if condition { if_true.eval(ctx).await } else { if_false.eval(ctx).await }
588588
}
589589

590+
/// Replaces matches of a regular expression pattern in the string. The replacement string supports backreferences: `$0` for the whole match, `$1`, `$2`, etc. for capture groups.
591+
#[node_macro::node(category("Text"))]
592+
fn regex_replace(
593+
_: impl Ctx,
594+
string: String,
595+
/// The regular expression pattern to search for.
596+
pattern: String,
597+
/// The replacement string. Use `$0` for the whole match, `$1`, `$2`, etc. for capture groups.
598+
replacement: String,
599+
/// Replace all matches. When disabled, only the first match is replaced.
600+
#[default(true)]
601+
replace_all: bool,
602+
/// Match letters regardless of case.
603+
case_insensitive: bool,
604+
/// Make `^` and `$` match the start and end of each line, not just the whole string.
605+
multiline: bool,
606+
) -> String {
607+
let flags = match (case_insensitive, multiline) {
608+
(false, false) => "",
609+
(true, false) => "(?i)",
610+
(false, true) => "(?m)",
611+
(true, true) => "(?im)",
612+
};
613+
let full_pattern = format!("{flags}{pattern}");
614+
615+
let Ok(regex) = fancy_regex::Regex::new(&full_pattern) else {
616+
log::warn!("Invalid regex pattern: {pattern}");
617+
return string;
618+
};
619+
620+
if replace_all {
621+
regex.replace_all(&string, replacement.as_str()).into_owned()
622+
} else {
623+
regex.replace(&string, replacement.as_str()).into_owned()
624+
}
625+
}
626+
590627
/// Iterates over a list of strings, evaluating the mapped operation for each one. Use the *Read String* node to access the current string inside the loop.
591628
#[node_macro::node(category("Text"))]
592629
async fn map_string(

0 commit comments

Comments
 (0)