v1.15.2
ADDED: * Better docs for remap * Added returner convenience funcs for remap FIXED: * Proper resliced remap.ReMap.MapString
This commit is contained in:
@@ -5,6 +5,8 @@ Map returns a map[string][]<match bytes> for regexes with named capture groups m
|
||||
Note that this supports non-unique group names; [regexp.Regexp] allows for patterns with multiple groups
|
||||
using the same group name (though your IDE might complain; I know GoLand does).
|
||||
|
||||
It will panic if the embedded [regexp.Regexp] is nil.
|
||||
|
||||
Each match for each group is in a slice keyed under that group name, with that slice
|
||||
ordered by the indexing done by the regex match itself.
|
||||
|
||||
@@ -87,7 +89,7 @@ In detail, matches and/or its values may be nil or empty under the following con
|
||||
IF inclNoMatch is true
|
||||
IF inclNoMatchStrict is true
|
||||
THEN matches[<group name>] is defined and non-nil, but populated with placeholder nils
|
||||
(matches[<group name>] == [][]byte{nil[, nil...]})
|
||||
(matches[<group name>] == [][]byte{nil[, nil, ...]})
|
||||
ELSE
|
||||
THEN matches[<group name>] is guaranteed defined but may be nil (_, ok = matches[<group name>]; ok == true)
|
||||
ELSE
|
||||
@@ -109,7 +111,7 @@ func (r *ReMap) Map(b []byte, inclNoMatch, inclNoMatchStrict, mustMatch bool) (m
|
||||
return
|
||||
}
|
||||
|
||||
names = r.Regexp.SubexpNames()
|
||||
names = r.Regexp.SubexpNames()[:]
|
||||
matchBytes = r.Regexp.FindSubmatch(b)
|
||||
|
||||
if matchBytes == nil {
|
||||
@@ -204,13 +206,15 @@ func (r *ReMap) Map(b []byte, inclNoMatch, inclNoMatchStrict, mustMatch bool) (m
|
||||
}
|
||||
|
||||
/*
|
||||
MapString is exactly like ReMap.Map(), but operates on (and returns) strings instead.
|
||||
MapString is exactly like [ReMap.Map], but operates on (and returns) strings instead.
|
||||
(matches will always be nil if s == “.)
|
||||
|
||||
A small deviation, though; empty strings instead of nils (because duh) will occupy slice placeholders (if `inclNoMatchStrict` is specified).
|
||||
It will panic if the embedded [regexp.Regexp] is nil.
|
||||
|
||||
A small deviation and caveat, though; empty strings instead of nils (because duh) will occupy slice placeholders (if `inclNoMatchStrict` is specified).
|
||||
This unfortunately *does not provide any indication* if an empty string positively matched the pattern (a "hit") or if it was simply
|
||||
not matched at all (a "miss"). If you need definitive determination between the two conditions, it is instead recommended to either
|
||||
*not* use inclNoMatchStrict or to use ReMap.Map() instead and convert any non-nil values to strings after.
|
||||
*not* use inclNoMatchStrict or to use [ReMap.Map] instead and convert any non-nil values to strings after.
|
||||
|
||||
Particularly:
|
||||
|
||||
@@ -233,7 +237,7 @@ is provided but s does not match then matches will be:
|
||||
# inclNoMatchStrict
|
||||
|
||||
If true (and inclNoMatch is true), instead of a single nil the group's values will be
|
||||
a slice of eempty string values explicitly matching the number of times the group name is specified
|
||||
a slice of empty string values explicitly matching the number of times the group name is specified
|
||||
in the pattern.
|
||||
|
||||
For example, if a pattern:
|
||||
@@ -290,8 +294,8 @@ In detail, matches and/or its values may be nil or empty under the following con
|
||||
IF <group name> does not have a match
|
||||
IF inclNoMatch is true
|
||||
IF inclNoMatchStrict is true
|
||||
THEN matches[<group name>] is defined and non-nil, but populated with placeholder nils
|
||||
(matches[<group name>] == []string{""[, ""...]})
|
||||
THEN matches[<group name>] is defined and non-nil, but populated with placeholder strings
|
||||
(matches[<group name>] == []string{""[, "", ...]})
|
||||
ELSE
|
||||
THEN matches[<group name>] is guaranteed defined but may be nil (_, ok = matches[<group name>]; ok == true)
|
||||
ELSE
|
||||
@@ -334,7 +338,8 @@ func (r *ReMap) MapString(s string, inclNoMatch, inclNoMatchStrict, mustMatch bo
|
||||
return
|
||||
}
|
||||
/*
|
||||
I'm not entirely sure how serious they are about "the slice should not be modified"...
|
||||
I'm not entirely sure how serious they are about
|
||||
"the slice should not be modified"...
|
||||
|
||||
DO NOT sort or dedupe `names`! If the same name for groups is duplicated,
|
||||
it will be duplicated here in proper order and the ordering is tied to
|
||||
@@ -351,7 +356,7 @@ func (r *ReMap) MapString(s string, inclNoMatch, inclNoMatchStrict, mustMatch bo
|
||||
return
|
||||
}
|
||||
|
||||
if names == nil || len(names) <= 1 {
|
||||
if names == nil || len(names) == 0 || len(names) == 1 {
|
||||
/*
|
||||
No named capture groups;
|
||||
technically only the last condition would be the case,
|
||||
@@ -363,6 +368,7 @@ func (r *ReMap) MapString(s string, inclNoMatch, inclNoMatchStrict, mustMatch bo
|
||||
}
|
||||
return
|
||||
}
|
||||
names = names[1:]
|
||||
|
||||
if len(matchIndices) == 0 || len(matchIndices) == 1 {
|
||||
/*
|
||||
@@ -385,15 +391,15 @@ func (r *ReMap) MapString(s string, inclNoMatch, inclNoMatchStrict, mustMatch bo
|
||||
}
|
||||
return
|
||||
}
|
||||
matchIndices = matchIndices[2:]
|
||||
|
||||
/*
|
||||
A reslice of `matchIndices` could technically start at 2 (as long as `names` is sliced [1:])
|
||||
A reslice of `matchIndices` starts at 2 (as long as `names` is sliced [1:])
|
||||
because they're in pairs: []int{<start>, <end>, <start>, <end>, ...}
|
||||
and the first pair is the entire pattern match (un-resliced names[0]).
|
||||
Thus the len(matchIndices) == 2*len(names), *even* if you
|
||||
Thus the len(matchIndices) == 2*len(names), *even* if you reslice.
|
||||
Keep in mind that since the first element of names is removed,
|
||||
the first pair here is skipped.
|
||||
This provides a bit more consistent readability, though.
|
||||
we reslices matchIndices as well (above).
|
||||
*/
|
||||
idxChunks = make([][]int, len(names))
|
||||
chunkIdx = 0
|
||||
@@ -411,6 +417,7 @@ func (r *ReMap) MapString(s string, inclNoMatch, inclNoMatchStrict, mustMatch bo
|
||||
// group did not match
|
||||
chunkIndices = nil
|
||||
} else {
|
||||
// single character
|
||||
if chunkIndices[0] == chunkIndices[1] {
|
||||
chunkIndices = []int{chunkIndices[0]}
|
||||
} else {
|
||||
@@ -432,6 +439,7 @@ func (r *ReMap) MapString(s string, inclNoMatch, inclNoMatchStrict, mustMatch bo
|
||||
(which is either an *unnamed* capture group
|
||||
OR the first element in `names`, which is always
|
||||
the entire match).
|
||||
(We reslice out the latter.)
|
||||
*/
|
||||
if grpNm == "" {
|
||||
continue
|
||||
|
||||
Reference in New Issue
Block a user