Skip to content

Commit

Permalink
Escape slashes in replace pattern and replacement (#487)
Browse files Browse the repository at this point in the history
  • Loading branch information
hdwalters authored Sep 20, 2024
1 parent 9f76525 commit 6dc17df
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 11 deletions.
25 changes: 14 additions & 11 deletions src/std/text.ab
Original file line number Diff line number Diff line change
@@ -1,27 +1,29 @@
/// Finds the first occurrence of a pettern in the content and replaces it with the provided replacement text.
pub fun replace_once(source, pattern, replacement) {
return "\$\{source/{pattern}/{replacement}}"
/// Replaces all occurences of a pattern in the content with the provided replace text.
pub fun replace(source, search, replace) {
return "\$\{source//{search}/{replace}}"
}

/// Replaces all occurences of a pattern in the content with the provided replacement text.
pub fun replace(source, pattern, replacement) {
return "\$\{source//{pattern}/{replacement}}"
/// Replaces the first occurence of a pattern in the content with the provided replace text.
pub fun replace_once(source, search, replace) {
return "\$\{source/{search}/{replace}}"
}

/// Replaces all occurences of a regex pattern in the content with the provided replacement text.
/// Replaces all occurences of a regex pattern in the content with the provided replace text.
///
/// Function uses `sed`
pub fun replace_regex(source: Text, pattern: Text, replacement: Text, extended: Bool = false): Text {
pub fun replace_regex(source: Text, search: Text, replace: Text, extended: Bool = false): Text {
unsafe {
search = replace(search, "/", "\/")
replace = replace(replace, "/", "\/")
if extended {
// GNU sed versions 4.0 through 4.2 support extended regex syntax,
// but only via the "-r" option; use that if the version information
// contains "GNU sed".
$re='\bCopyright\b.+\bFree Software Foundation\b'; [[ \$(sed --version 2>/dev/null) =~ \$re ]]$
let flag = status == 0 then "-r" else "-E"
return $echo "{source}" | sed {flag} -e "s/{pattern}/{replacement}/g"$
return $echo "{source}" | sed {flag} -e "s/{search}/{replace}/g"$
} else {
return $echo "{source}" | sed -e "s/{pattern}/{replacement}/g"$
return $echo "{source}" | sed -e "s/{search}/{replace}/g"$
}
}
}
Expand Down Expand Up @@ -133,7 +135,7 @@ pub fun ends_with(text: Text, suffix: Text): Bool {
}

/// Returns a substring from `text` starting at the given `index` (0-based).
///
///
/// If `index` is negative, the substring starts from the end of `text` based on the absolute value of `index`.
/// If `length` is provided, the substring will include `length` characters; otherwise, it slices to the end of `text`.
/// If `length` is negative, an empty string is returned.
Expand All @@ -144,6 +146,7 @@ pub fun slice(text: Text, index: Num, length: Num = 0): Text {
}

/// Returns the character from `text` at the specified `index` (0-based).
///
/// If `index` is negative, the substring starts from the end of `text` based on the absolute value of `index`.
pub fun char_at(text: Text, index: Num): Text {
return unsafe $printf "%.1s" "\$\{text:{index}}"$
Expand Down
4 changes: 4 additions & 0 deletions src/tests/stdlib/replace_regex_basic.ab
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@ import * from "std/text"

// Output
// abc[123]def
// aeon aeons ### eons
// #path#to#file.txt

main {
echo replace_regex("abc123def", "\([0-9][0-9]*\)", "[\1]")
echo replace_regex("aeon aeons eon eons", "\beon\b", "###")
echo replace_regex("/path/to/file.txt", "/", "#")
}
4 changes: 4 additions & 0 deletions src/tests/stdlib/replace_regex_ext.ab
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,13 @@ import * from "std/text"

// Output
// abc[123]def
// aeon aeons ### eons
// #path#to#file.txt

main {
// This will fail on any system where sed does not support extended
// regex syntax, via "-r" on GNU sed and "-E" on all other versions.
echo replace_regex("abc123def", "([0-9]+)", "[\1]", true)
echo replace_regex("aeon aeons eon eons", "\beon\b", "###", true)
echo replace_regex("/path/to/file.txt", "/", "#", true)
}

0 comments on commit 6dc17df

Please sign in to comment.