Skip to content

Commit 22f68d4

Browse files
authored
Merge pull request #37 from mgomes/string-methods-phase6
Add phase-6 regex, byte helpers, and bang parity
2 parents 1c92028 + b57b290 commit 22f68d4

File tree

5 files changed

+403
-60
lines changed

5 files changed

+403
-60
lines changed

docs/strings.md

Lines changed: 49 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,31 @@ Alias for `size`, returns the number of characters:
1212
"héllo".length # 5
1313
```
1414

15+
### `bytesize`
16+
17+
Returns the number of bytes in UTF-8 encoding:
18+
19+
```vibe
20+
"hé".bytesize # 3
21+
```
22+
23+
### `ord`
24+
25+
Returns the codepoint of the first character:
26+
27+
```vibe
28+
"hé".ord # 104
29+
```
30+
31+
### `chr`
32+
33+
Returns the first character (or `nil` for empty strings):
34+
35+
```vibe
36+
"hé".chr # "h"
37+
"".chr # nil
38+
```
39+
1540
### `empty?`
1641

1742
Returns true when the string has no characters:
@@ -130,6 +155,22 @@ Returns true when `substring` appears in the string:
130155
"vibescript".include?("script") # true
131156
```
132157

158+
### `match(pattern)`
159+
160+
Regex match returning `[full, capture1, ...]` or `nil`:
161+
162+
```vibe
163+
"ID-12 ID-34".match("ID-([0-9]+)") # ["ID-12", "12"]
164+
```
165+
166+
### `scan(pattern)`
167+
168+
Regex scan returning all full matches:
169+
170+
```vibe
171+
"ID-12 ID-34".scan("ID-[0-9]+") # ["ID-12", "ID-34"]
172+
```
173+
133174
### `index(substring, offset = 0)`
134175

135176
Returns the first character index for `substring`, or `nil` when not found:
@@ -159,20 +200,22 @@ Returns a character or substring; returns `nil` when out of bounds:
159200
"héllo".slice(99) # nil
160201
```
161202

162-
### `sub(pattern, replacement)`
203+
### `sub(pattern, replacement, regex: false)`
163204

164-
Replaces the first occurrence of `pattern` (string-only):
205+
Replaces the first occurrence of `pattern`:
165206

166207
```vibe
167208
"bananas".sub("na", "NA") # "baNAnas"
209+
"ID-12 ID-34".sub("ID-[0-9]+", "X", regex: true) # "X ID-34"
168210
```
169211

170-
### `gsub(pattern, replacement)`
212+
### `gsub(pattern, replacement, regex: false)`
171213

172-
Replaces all occurrences of `pattern` (string-only):
214+
Replaces all occurrences of `pattern`:
173215

174216
```vibe
175217
"bananas".gsub("na", "NA") # "baNANAs"
218+
"ID-12 ID-34".gsub("ID-[0-9]+", "X", regex: true) # "X X"
176219
```
177220

178221
### `delete_prefix(prefix)`
@@ -222,7 +265,8 @@ Returns `replacement`:
222265

223266
### Bang aliases
224267

225-
The following methods are supported as aliases and return transformed strings:
268+
The following methods are supported as aliases and return transformed strings.
269+
When there is no change, bang methods return `nil`.
226270

227271
- `strip!`, `lstrip!`, `rstrip!`, `chomp!`
228272
- `delete_prefix!`, `delete_suffix!`

examples/strings/operations.vibe

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,16 +18,25 @@ def run
1818
sample = " Vibescript Example "
1919
indexed = "héllo hello"
2020
immutable = " hello "
21+
ids = "ID-12 ID-34"
2122
{
2223
normalized: normalize(sample),
24+
bytesize: "hé".bytesize,
25+
ord: "hé".ord,
26+
chr: "hé".chr,
2327
upper: sample.strip.upcase,
2428
lower: sample.strip.downcase,
2529
capitalize: "hÉLLo wORLD".capitalize,
2630
swapcase: "Hello VIBE".swapcase,
2731
reverse: "héllo".reverse,
2832
sub: "bananas".sub("na", "NA"),
2933
gsub: "bananas".gsub("na", "NA"),
34+
sub_regex: ids.sub("ID-[0-9]+", "X", regex: true),
35+
gsub_regex: ids.gsub("ID-[0-9]+", "X", regex: true),
36+
match: ids.match("ID-([0-9]+)"),
37+
scan: ids.scan("ID-[0-9]+"),
3038
strip_bang: immutable.strip!,
39+
strip_bang_nochange: "hello".strip!,
3140
immutable_after: immutable,
3241
clear: "hello".clear,
3342
concat: "he".concat("llo", "!"),

vibes/examples_test.go

Lines changed: 43 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1519,41 +1519,49 @@ func TestExamples(t *testing.T) {
15191519
file: "strings/operations.vibe",
15201520
function: "run",
15211521
want: hashVal(map[string]Value{
1522-
"normalized": strVal("vibescript example"),
1523-
"upper": strVal("VIBESCRIPT EXAMPLE"),
1524-
"lower": strVal("vibescript example"),
1525-
"capitalize": strVal("Héllo world"),
1526-
"swapcase": strVal("hELLO vibe"),
1527-
"reverse": strVal("olléh"),
1528-
"sub": strVal("baNAnas"),
1529-
"gsub": strVal("baNANAs"),
1530-
"strip_bang": strVal("hello"),
1531-
"immutable_after": strVal(" hello "),
1532-
"clear": strVal(""),
1533-
"concat": strVal("hello!"),
1534-
"concat_noop": strVal("hello"),
1535-
"replace": strVal("new"),
1536-
"sub_bang": strVal("baNAnas"),
1537-
"gsub_bang": strVal("baNANAs"),
1538-
"lstrip": strVal("hello\t"),
1539-
"rstrip": strVal("\thello"),
1540-
"chomp_default": strVal("line"),
1541-
"chomp_custom": strVal("path//"),
1542-
"delete_prefix": strVal("happy"),
1543-
"delete_suffix": strVal("report"),
1544-
"split_default": arrayVal(strVal("one"), strVal("two"), strVal("three")),
1545-
"split_custom": arrayVal(strVal("a"), strVal("b"), strVal("c")),
1546-
"tags": arrayVal(strVal("ruby"), strVal("go"), strVal("vibescript")),
1547-
"empty_true": boolVal(true),
1548-
"empty_false": boolVal(false),
1549-
"starts": boolVal(true),
1550-
"ends": boolVal(true),
1551-
"include": boolVal(true),
1552-
"index": intVal(2),
1553-
"rindex": intVal(8),
1554-
"slice_char": strVal("é"),
1555-
"slice_range": strVal("éllo"),
1556-
"length": intVal(5),
1522+
"normalized": strVal("vibescript example"),
1523+
"bytesize": intVal(3),
1524+
"ord": intVal(104),
1525+
"chr": strVal("h"),
1526+
"upper": strVal("VIBESCRIPT EXAMPLE"),
1527+
"lower": strVal("vibescript example"),
1528+
"capitalize": strVal("Héllo world"),
1529+
"swapcase": strVal("hELLO vibe"),
1530+
"reverse": strVal("olléh"),
1531+
"sub": strVal("baNAnas"),
1532+
"gsub": strVal("baNANAs"),
1533+
"sub_regex": strVal("X ID-34"),
1534+
"gsub_regex": strVal("X X"),
1535+
"match": arrayVal(strVal("ID-12"), strVal("12")),
1536+
"scan": arrayVal(strVal("ID-12"), strVal("ID-34")),
1537+
"strip_bang": strVal("hello"),
1538+
"strip_bang_nochange": nilVal(),
1539+
"immutable_after": strVal(" hello "),
1540+
"clear": strVal(""),
1541+
"concat": strVal("hello!"),
1542+
"concat_noop": strVal("hello"),
1543+
"replace": strVal("new"),
1544+
"sub_bang": strVal("baNAnas"),
1545+
"gsub_bang": strVal("baNANAs"),
1546+
"lstrip": strVal("hello\t"),
1547+
"rstrip": strVal("\thello"),
1548+
"chomp_default": strVal("line"),
1549+
"chomp_custom": strVal("path//"),
1550+
"delete_prefix": strVal("happy"),
1551+
"delete_suffix": strVal("report"),
1552+
"split_default": arrayVal(strVal("one"), strVal("two"), strVal("three")),
1553+
"split_custom": arrayVal(strVal("a"), strVal("b"), strVal("c")),
1554+
"tags": arrayVal(strVal("ruby"), strVal("go"), strVal("vibescript")),
1555+
"empty_true": boolVal(true),
1556+
"empty_false": boolVal(false),
1557+
"starts": boolVal(true),
1558+
"ends": boolVal(true),
1559+
"include": boolVal(true),
1560+
"index": intVal(2),
1561+
"rindex": intVal(8),
1562+
"slice_char": strVal("é"),
1563+
"slice_range": strVal("éllo"),
1564+
"length": intVal(5),
15571565
}),
15581566
},
15591567
}

0 commit comments

Comments
 (0)