为何re-find返回含两个元素的向量?预期单个值却不符的原因
re-find Behavior: Two Common Questions Answered Let’s tackle your two questions about re-find one by one—this is super common confusion, so you’re not alone!
1. Why does re-find return a vector with two elements?
The short answer: your regular expression includes a capture group (parentheses), and re-find returns a vector where:
- The first element is the entire substring that matched the full regex pattern
- Each subsequent element is the content matched by each capture group in order
For example:
(re-find #"(\d+)" "My age is 30") ;; Returns ["30" "30"]
Here, the full regex (\d+) matches the substring "30", and the capture group (\d+) also captures "30"—hence the two-element vector. If you had multiple capture groups, you’d get more elements:
(re-find #"(\w+) (\w+)" "John Doe") ;; Returns ["John Doe" "John" "Doe"]
If you don’t want the capture group to add an element to the result, use a non-capturing group (?:...) instead:
(re-find #"(?:\d+)" "My age is 30") ;; Returns "30" (just the full match, no extra vector element)
2. Why does my specific re-find usage return something other than the single value I expected?
This almost always ties back to how capture groups work (like the first question) or a mismatch between your regex pattern and the target string. Let’s cover the most common scenarios:
Scenario 1: You expected only the capture group value, not the full match
If you wrote something like:
(re-find #"(\w+)" "Hello World") ;; Returns ["Hello" "Hello"] instead of just "Hello"
You’re seeing the full match plus the capture group. To get just the capture group value, use second to grab the second element of the vector:
(second (re-find #"(\w+)" "Hello World")) ;; Returns "Hello"
Scenario 2: Your regex has unintended capture groups
Maybe you added parentheses for grouping (like alternation) but forgot they’re capture groups. For example:
(re-find #"cat|dog" "I have a cat") ;; Returns "cat" (single value, no capture groups) (re-find #"(cat|dog)" "I have a cat") ;; Returns ["cat" "cat"] (unintended capture group adds an element)
Fix this by using non-capturing groups for alternation:
(re-find #"(?:cat|dog)" "I have a cat") ;; Returns "cat" (single value as expected)
Scenario 3: Your regex isn’t matching what you think it is
Sometimes the issue isn’t re-find itself—it’s that your regex pattern doesn’t align with the target string. For example, if you use anchors like ^ (start of string) or $ (end of string) incorrectly:
(re-find #"^cat" "I have a cat") ;; Returns nil (because "cat" isn’t at the start of the string)
Double-check your regex to make sure it’s targeting the substring you actually want to match.
内容的提问来源于stack exchange,提问作者THX1137

