NAME

Sidef::Types::Regex::Regex - Regular expression type for pattern matching, searching, and text substitution.

DESCRIPTION

This class implements regular expression pattern matching functionality in Sidef. The Regex class provides methods for compiling patterns, matching against strings, comparing patterns, and combining patterns together.

Regular expressions in Sidef support standard Perl-compatible regular expression syntax, including character classes, quantifiers, anchors, capturing groups, and various modifiers.

A regex constructed with the trailing g modifier (e.g. /\d+/g, or Regex('\d+', 'g')) behaves as a stepping regex: each match — whether performed through "match" (or its aliases run/=~) or the dedicated global-matching methods — starts where the previous one on that same object left off, and a failed match resets that internal position back to the start. Use "global_match" or "global_matches" if you want this stepping behavior on a regex that was not itself built with the g modifier.

SYNOPSIS

# Create a regex object
var regex = /\d+/
var regex2 = Regex('\w+', 'i')  # case-insensitive

# Match against a string
if (("hello123" =~ /\d+/)) {
    say "Found digits!"
}

# Extract all matches
var matches = /(\d+)/.gmatches("abc123def456")
say matches  # [123, 456]

# Concatenate regexes
var combined = (/foo/ + /bar/)  # matches "foobar"

INHERITS

Inherits methods from Sidef::Object::Object.

CONSTRUCTION

new

Regex.new(pattern, mode)
Regex(pattern, mode)

Compiles a new Regex object from a pattern string and an optional modifier string. Both pattern and mode may be given as plain strings or as string-like objects (they are stringified automatically).

var re1 = Regex('\d+')
var re2 = Regex('\w+', 'i')       # case-insensitive
var re3 = Regex('^start', 'gm')   # global + multi-line

Recognized modifier letters include i (case-insensitive), s (single-line, dot matches newline), m (multi-line, ^/$ match line boundaries), x (extended, ignore whitespace/comments in the pattern), and the special g (global/stepping matching, handled separately from the others — see "DESCRIPTION").

Aliases: call

MATCHING

match

self.match(string)
self.match(string, pos)

Matches the regex pattern against a string, returning a Sidef::Types::Regex::Match object. The Match object is truthy if the pattern was found. An optional starting offset pos may be given to begin the search partway through the string; this is only meaningful for non-stepping regexes (see "DESCRIPTION") since a stepping regex tracks its own position internally.

var text = "Hello, World!"
var match = (text =~ /(W\w+)/)

if (match) {
    say match  # "World"
}

# With capturing groups
if ("age: 25" =~ /(\d+)/) { |m|
    say m[0]  # 25
}

# With an explicit starting offset
var m = "aaa".match(/(a+)/, 1)

Aliases: run, =~

global_match

self.global_match(string)
self.global_match(string, pos)

Performs a single step of a global (stepping) match against string, regardless of whether this regex was itself built with the g modifier. Returns a Sidef::Types::Regex::Match object.

Called without pos, each call continues from wherever the previous global match on this regex left off — so repeated calls walk through the successive matches in the string one at a time, and a failed call resets the internal position back to the start, ready to begin again.

var text = "abc123def456ghi789"
var re = /(\d+)/

var m1 = re.global_match(text)
say m1  # 123
var m2 = re.global_match(text)
say m2  # 456
var m3 = re.global_match(text)
say m3  # 789
var m4 = re.global_match(text)
say m4.matched  # false — and the internal position has reset

Passing an explicit pos performs a one-off match starting at that offset without disturbing the ongoing stepping position, so it's safe to use for a quick look-ahead in the middle of an iteration:

re.global_match(text)          # advances the internal position
re.global_match(text, 0)       # a one-off probe at offset 0; doesn't disturb the above
re.global_match(text)          # continues from where the first call left off

Aliases: gmatch

global_matches

self.global_matches(string)
self.global_matches(string, pos)
self.global_matches(string, block)
self.global_matches(string, pos, block)

Finds all successive matches of the regex pattern in string, driven by the same stepping mechanism as "global_match", and returns them as an array. The optional arguments after string may be given in either order: a Number sets the starting offset, and a Block is invoked for each match (as block.run(index, match)), with the block's return value collected in place of the raw Match object.

The scan stops automatically once the match position stops advancing, which protects against infinite loops on patterns that can match a zero-width string.

var text = "The year 2024 has 365 days"
var numbers = /(\d+)/.gmatches(text)
say numbers  # [2024, 365]

# Starting from an offset
var more = /(\d+)/.gmatches("a1b2c3d4", 4)

# With a block, transforming each match
var tagged = /(\d+)/.gmatches(text, { |i, m| "match ##{i}: #{m}" })

Aliases: gmatches, all_matches, map_matches, repeated_match

COMBINING REGEXES

add

a + b

Concatenates two regular expressions (or a regex and a string) to create a new regex that matches the first pattern followed immediately by the second.

var re1 = /foo/
var re2 = /bar/
var combined = (re1 + re2)  # matches "foobar"

say (("foobar" =~ combined) ? true : false)   # true
say (("foo bar" =~ combined) ? true : false)  # false

The resulting regex still matches correctly, but note that its own dump/to_s representation embeds the operands' already-compiled forms rather than a clean concatenation of their raw pattern text — see "NOTES".

Aliases: concat, +

union

a | b

Builds a new regex from the raw pattern text of both operands, inserting | between them. If the right-hand side is a plain string, it is treated literally and quoted before being added.

The modifiers of both operands are merged into the result. If the same flag appears more than once across the inputs, the resulting regex preserves the highest repetition count seen for that flag. The global/stepping flag is kept if either operand has it. Any extra modifier letters passed as a third argument are appended to the merged flags before the final regex is built.

var re = (/cat/ | /dog/)

This produces a regex equivalent to /cat|dog/.

A literal string on the right-hand side is escaped automatically:

var re = (/cat/ | "d.g")

This produces a regex equivalent to /cat|d\.g/.

An optional third argument lets you add extra modifier letters when calling this as a method:

var re2 = /foo/i.union(/bar/m, 'x')

Aliases: |

COMPARISON

eq

a == b

Tests whether two regular expressions are equal, by comparing their compiled forms (pattern text plus embedded modifiers such as i, m, s, x).

var re1 = /abc/i
var re2 = /abc/i
var re3 = /abc/

say ((re1 == re2) ? true : false)  # true
say ((re1 == re3) ? true : false)  # false (different modifiers)

The g (stepping) modifier is tracked separately from the compiled pattern and is not reflected in this comparison — see "NOTES".

Aliases: ==

ne

a != b

The negation of "eq": true if the regex patterns differ in their compiled form.

var re1 = /abc/
var re2 = /xyz/
say ((re1 != re2) ? true : false)  # true

Aliases: !=,

cmp

a <=> b

Performs a three-way comparison between two regular expressions based on their compiled string form. Returns -1, 0, or 1.

var re1 = /abc/
var re2 = /xyz/
say (re1 <=> re2)  # -1

var re3 = /abc/
say (re1 <=> re3)  # 0

Aliases: <=>

lt

a < b

Returns true if the first regex is lexicographically less than the second, based on "cmp".

var re1 = /abc/
var re2 = /xyz/
say ((re1 < re2) ? true : false)  # true

Aliases: <

le

a <= b

Returns true if the first regex is lexicographically less than or equal to the second, based on "cmp".

var re1 = /abc/
var re2 = /abc/
say ((re1 <= re2) ? true : false)  # true

Aliases: <=,

gt

a > b

Returns true if the first regex is lexicographically greater than the second, based on "cmp".

var re1 = /xyz/
var re2 = /abc/
say ((re1 > re2) ? true : false)  # true

Aliases: >

ge

a >= b

Returns true if the first regex is lexicographically greater than or equal to the second, based on "cmp".

var re1 = /xyz/
var re2 = /abc/
say ((re1 >= re2) ? true : false)  # true

Aliases: >=,

CONVERSION

to_regex

self.to_regex

Returns the regex object itself, unchanged. Provided for interface compatibility in places that expect a "convert to Regex" method.

var regex = /test/i
var same = regex.to_regex
say ((regex == same) ? true : false)  # true

Aliases: to_re

dump

self.dump

Returns a string representation of the regular expression in slash-delimited form, including its pattern and modifiers, e.g. /hello/i.

var regex = /hello/i
say regex.dump  # /hello/i

var complex = /\d{3}-\d{4}/
say complex.dump  # /\d{3}-\d{4}/

Note that this differs from a Regex object's implicit stringification (e.g. via string interpolation), which instead shows Perl's own compiled-pattern form (something like (?^i:hello)).

Aliases: to_s, to_str

LOW-LEVEL ACCESS

get_value

self.get_value

Returns the underlying compiled pattern object backing this Regex, used internally to implement string, boolean, and numeric context conversions. In boolean context a Regex object is always true, since it is always a defined compiled pattern (unlike a Match object, whose truthiness reflects whether it actually matched). Prefer "dump" for a readable string form.

REGEX MODIFIERS

Sidef supports various regex modifiers that can be applied when creating regular expressions:

  • i - Case-insensitive matching

  • s - Single-line mode (dot matches newlines)

  • m - Multi-line mode (^ and $ match line boundaries)

  • x - Extended mode (ignore whitespace and comments in pattern)

  • g - Stepping/global matching (see "DESCRIPTION")

Example usage:

var case_insensitive = /hello/i
var multiline = /^start/m
var combined = /pattern/ims

EXAMPLES

Extracting All Numbers From Text

var text = "The year 2024 has 365 days"
var numbers = /(\d+)/.gmatches(text)
say numbers  # [2024, 365]

Stepping Through Matches One at a Time

var re = /(\d+)/
var text = "a1b2c3"

loop {
    var m = re.global_match(text)
    m.matched || break
    say m
}

Building a Pattern From Parts

var word = /\w+/
var space = /\s+/
var two_words = (word + space + word)

say ((("Hello World" =~ two_words)) ? true : false)  # true

Comparing Regexes

var re1 = /abc/i
var re2 = /abc/i

say ((re1 == re2) ? true : false)  # true

SEE ALSO

NOTES

The g modifier is tracked separately from the compiled pattern, so two regexes that differ only in whether they have a trailing g compare as equal under "eq"/"ne"/"cmp" and the related operators.