pattern: fix captures, add split and global-match-str

This commit is contained in:
hellerve 2020-02-09 13:42:39 +01:00
parent d7cf3982f8
commit 66431a4c80
3 changed files with 38 additions and 9 deletions

View File

@ -39,6 +39,30 @@ If you want to replace all occurrences of the pattern, use `-1`.")
(doc from-chars "creates a pattern that matches a group of characters from a list of those characters.")
(defn from-chars [chars]
(Pattern.init &(str* @"[" (String.from-chars chars) @"]")))
(defn global-match-str [p s]
(Array.copy-map &Array.unsafe-first &(global-match p s)))
(doc split "splits a string by a pattern.")
(defn split [p s]
(let-do [idx (find-all p s)
strs (global-match-str p s)
lidx (Array.length &idx)
result (Array.allocate (Int.inc lidx))]
(Array.aset-uninitialized! &result 0
(substring s 0 (if (> lidx 0) @(Array.unsafe-nth &idx 0) (length s))))
(for [i 0 (Int.dec (Array.length &idx))]
(let [plen (length (Array.unsafe-nth &strs i))]
(Array.aset-uninitialized! &result (Int.inc i)
(substring s (+ @(Array.unsafe-nth &idx i) plen)
@(Array.unsafe-nth &idx (Int.inc i))))))
(when (> lidx 0)
(let [plen (length (Array.unsafe-nth &strs (Int.dec lidx)))]
(Array.aset-uninitialized! &result lidx
(suffix-string s (+ @(Array.unsafe-nth &idx (Int.dec lidx))
plen)))))
result))
)
(defmodule String
@ -84,7 +108,7 @@ If you want to replace all occurrences of the pattern, use `-1`.")
(doc chomp "trims a newline from the end of a string.")
(defn chomp [s]
(Pattern.substitute #"\n$" s "" 1))
(Pattern.substitute #"\r$" &(Pattern.substitute #"\n$" s "" 1) "" 1))
(doc collapse-whitespace "collapses groups of whitespace into single spaces.")
(defn collapse-whitespace [s]

View File

@ -309,11 +309,13 @@ init: /* using goto's to optimize tail recursion */
case 't': { /* tab? */
char h = *(p + 1);
p += 2;
if ( (*s == '\r' && h == 'r')
|| (*s == '\n' && h == 'n')
|| (*s == '\t' && h == 't')
) { s++; goto init; }
else s = NULL;
if ((*s == '\r' && h == 'r') ||
(*s == '\n' && h == 'n') ||
(*s == '\t' && h == 't')) {
s++;
goto init;
} else
s = NULL;
break;
}
case '0':
@ -424,7 +426,7 @@ Array Pattern_internal_push_onecapture(PatternMatchState *ms, int i, String s,
if (i >= ms->level) {
if (!i)
return Array_push_String(captures, s, i,
ms->capture[i].len); /* add whole match */
e - s); /* add whole match */
else
carp_regerror("invalid capture index %cd", C_ESC, i + 1);
} else {

View File

@ -61,8 +61,7 @@
"matches? works as exptected II")
(assert-equal test
true
(and* (matches? #"\n" "\n") (matches? #"\n" "\r")
(matches? #"\n" "\r\n"))
(and (matches? #"\n" "\n") (matches? #"\r" "\r"))
"matches? works as exptected on newlines special case")
(assert-equal test
true
@ -84,6 +83,10 @@
"sub 2-3 3-4"
&(substitute #"(\d)-(\d)" "1-2 2-3 3-4" "sub" 1)
"substitute works as expected")
(assert-equal test
&[@"" @"1" @"2" @"3" @""]
&(split #"\-\-" "--1--2--3--")
"split works as expected")
(assert-equal test
"sub sub sub"
&(substitute #"(\d)-(\d)" "1-2 2-3 3-4" "sub" -1)