diff --git a/Sources/StencilSwiftKit/Environment.swift b/Sources/StencilSwiftKit/Environment.swift index d73127ee..52312743 100644 --- a/Sources/StencilSwiftKit/Environment.swift +++ b/Sources/StencilSwiftKit/Environment.swift @@ -7,7 +7,7 @@ import Stencil public extension Extension { - public func registerStencilSwiftExtensions() { + func registerStencilSwiftExtensions() { registerTags() registerStringsFilters() registerNumbersFilters() diff --git a/Sources/StencilSwiftKit/Filters+Strings.swift b/Sources/StencilSwiftKit/Filters+Strings.swift index fde13126..afa7e7f2 100644 --- a/Sources/StencilSwiftKit/Filters+Strings.swift +++ b/Sources/StencilSwiftKit/Filters+Strings.swift @@ -95,7 +95,7 @@ extension Filters.Strings { while idx < scalars.endIndex, let scalar = UnicodeScalar(scalars[idx].value), characterSet.contains(scalar) { idx = scalars.index(after: idx) } - if idx > scalars.index(after: start) && idx < scalars.endIndex, + if !string.isEmpty && idx > scalars.index(after: start) && idx < scalars.endIndex, let scalar = UnicodeScalar(scalars[idx].value), CharacterSet.lowercaseLetters.contains(scalar) { idx = scalars.index(before: idx) @@ -264,9 +264,22 @@ extension Filters.Strings { let source = try Filters.parseString(from: value) let substring = try Filters.parseStringArgument(from: arguments, at: 0) let replacement = try Filters.parseStringArgument(from: arguments, at: 1) + if substring.first == "/" && substring.last == "/" { + let regex = String(substring.dropFirst().dropLast()) + return replaceRegex(source: source, regex: regex, replacement: replacement) + } return source.replacingOccurrences(of: substring, with: replacement) } + /// Replaces in the given string the given regular expression with the replacement + /// - Parameters: + /// - source: The source string + /// - regex: The regular expression + /// - replacement: The replacement string + private static func replaceRegex(source: String, regex: String, replacement: String) -> String { + return source.replacingOccurrences(of: regex, with: replacement, options: .regularExpression) + } + /// Converts an arbitrary string to a valid swift identifier. Takes an optional Mode argument: /// - normal (default): uppercase the first character, prefix with an underscore if starting /// with a number, replace invalid characters by underscores diff --git a/Tests/StencilSwiftKitTests/StringFiltersTests.swift b/Tests/StencilSwiftKitTests/StringFiltersTests.swift index 707a2a0f..5a5e80dc 100644 --- a/Tests/StencilSwiftKitTests/StringFiltersTests.swift +++ b/Tests/StencilSwiftKitTests/StringFiltersTests.swift @@ -470,11 +470,12 @@ extension StringFiltersTests { extension StringFiltersTests { func testReplace() throws { - let expectations = [ + let expectations: [(Input, String, String, String)] = [ (Input(string: "string"), "ing", "oke", "stroke"), (Input(string: "string"), "folks", "mates", "string"), (Input(string: "hi mates!"), "hi", "Yo", "Yo mates!"), - (Input(string: "string with spaces"), " ", "_", "string_with_spaces") + (Input(string: "string with spaces"), " ", "_", "string_with_spaces"), + (Input(string: "string with numbers 42"), "/\\s\\d+$/", "", "string with numbers") ] for (input, substring, replacement, expected) in expectations {