stringifor_regex
StringiFor, regular expressions: a Pike VM, linear in the subject.
A pattern is parsed into a syntax tree, compiled into a program of a small virtual machine and run by a Pike VM: a simulation of the Thompson NFA that carries the capture positions with each thread. The time is O(n m), n the length of the subject and m the size of the program, whatever the pattern: there is no backtracking. Among the matches starting at the leftmost position the VM picks the one a backtracking engine (Perl, Python) would find first.
Matching is by unit, as the rest of StringiFor: a well-formed UTF-8 sequence, or a single byte that is not part of one. Internally a unit is a code: its codepoint, or U+DC00 + b for an ill-formed byte b, as Python's surrogateescape.
Source: src/lib/stringifor_regex.F90
Dependencies
Contents
- regex
- regex_match
- parser
- re_search
- re_fullmatch
- re_findall
- re_split
- re_sub
- compile
- add_thread
- all_matches
- parse_template
- add_piece
- fail
- set_flag
- parse_global_flags
- new_node
- add_child
- parse_alternation
- parse_concatenation
- parse_repeat
- quantifier
- read_count
- parse_atom
- new_group
- grow_names
- parse_escape
- escape_code
- new_class
- add_range
- add_escape_class
- add_complement
- close_class
- parse_class
- class_item
- sort_ranges
- emit
- compile_node
- set_split
- is_compiled
- group_count
- group_index
- search_character
- search_string
- match_character
- match_string
- fullmatch_character
- fullmatch_string
- finditer_character
- finditer_string
- findall_character
- findall_string
- split_character
- split_string
- sub_character
- sub_string
- span_number
- span_name
- group_number
- group_name
- groups
- name_index
- run
- assertion
- is_word
- fold
- in_class
- to_int
- re_search_cc
- re_search_cr
- re_search_sc
- re_search_sr
- re_fullmatch_cc
- re_fullmatch_cr
- re_fullmatch_sc
- re_fullmatch_sr
- re_findall_cc
- re_findall_cr
- re_findall_sc
- re_findall_sr
- re_split_cc
- re_split_cr
- re_split_sc
- re_split_sr
- re_sub_cc
- re_sub_cr
- re_sub_sc
- re_sub_sr
- is_identifier
- hex_value
- nullable
- itoa
Variables
| Name | Type | Attributes | Description |
|---|---|---|---|
MAX_PROGRAM | integer | parameter | Largest program, in instructions. |
MAX_DEPTH | integer | parameter | Deepest nesting of groups. |
MAX_REPEAT | integer | parameter | Largest count of a {m,n} quantifier. |
MAX_GROUPS | integer | parameter | Most capturing groups. |
MAX_CODE | integer | parameter | Largest code of a unit (U+10FFFF). |
BYTE_BASE | integer | parameter | Code of the ill-formed byte b: BYTE_BASE + b (U+DC00 + b). |
BACKSLASH | character(len=1) | parameter | Backslash (nvfortran reads backslash escapes in literals). |
OP_CHAR | integer | parameter | Match the unit of code arg1. |
OP_CHARI | integer | parameter | Match the unit of code arg1, ASCII case ignored (arg1 is lowercase). |
OP_ANY | integer | parameter | Match any unit but LF. |
OP_ANYNL | integer | parameter | Match any unit. |
OP_CLASS | integer | parameter | Match a unit of the class arg1. |
OP_SPLIT | integer | parameter | Continue at arg1 (preferred) and at arg2. |
OP_JMP | integer | parameter | Continue at arg1. |
OP_SAVE | integer | parameter | Save the position into the slot arg1. |
OP_ASSERT | integer | parameter | Continue if the assertion arg1 holds at the position. |
OP_MARK | integer | parameter | Save the position into the register arg1 (start of a loop iteration). |
OP_CHECK | integer | parameter | Continue at arg2 if the iteration was empty (register arg1 = position), else at arg3. |
OP_MATCH | integer | parameter | A match. |
AS_BOT | integer | parameter | \A, and ^ without m: start of the subject. |
AS_EOT | integer | parameter | \z (\Z): end of the subject. |
AS_MBOL | integer | parameter | ^ with m: start of a line. |
AS_EOL | integer | parameter | $ without m: end of the subject, or before a LF ending it. |
AS_MEOL | integer | parameter | $ with m: end of a line. |
AS_WORDB | integer | parameter | \b: a word boundary (ASCII word characters). |
AS_NWORDB | integer | parameter | \B: not a word boundary. |
N_EMPTY | integer | parameter | Nothing. |
N_LIT | integer | parameter | A unit, code val1. |
N_ANY | integer | parameter | The dot. |
N_CLASS | integer | parameter | A class, index val1. |
N_ASSERT | integer | parameter | An assertion, kind val1. |
N_GROUP | integer | parameter | A group, capturing if val1 > 0 (its number): one child. |
N_CAT | integer | parameter | A concatenation of the children. |
N_ALT | integer | parameter | An alternation of the children. |
N_REPEAT | integer | parameter | The child repeated val1 to val2 times (val2 < 0: no limit), greedy if val3 = 1. |
Derived Types
regex
A compiled regular expression.
Compile it with compile, then match it with search, match or fullmatch.
Components
| Name | Type | Attributes | Description |
|---|---|---|---|
compiled | logical | True once compiled. | |
ngroups | integer | Number of capturing groups. | |
nregs | integer | Number of loop registers. | |
op | integer | allocatable | Instructions. |
arg1 | integer | allocatable | First argument of the instructions. |
arg2 | integer | allocatable | Second argument of the instructions. |
arg3 | integer | allocatable | Third argument of the instructions. |
ranges | integer(kind=I4P) | allocatable | Ranges [first, last] of codes of all the classes. |
class_first | integer | allocatable | First range of each class. |
class_last | integer | allocatable | Last range of each class. |
class_negated | logical | allocatable | True if the class is negated. |
names | type(string) | allocatable | Name of each group, null if unnamed. |
Type-Bound Procedures
| Name | Attributes | Description |
|---|---|---|
compile | pass(self) | Compile a pattern. |
is_compiled | pass(self) | Return true if the regex is compiled. |
group_count | pass(self) | Return the number of capturing groups. |
group_index | pass(self) | Return the number of a named group, 0 if there is none. |
search | Search the leftmost match. | |
match | Match at the start. | |
fullmatch | Match the whole subject. | |
finditer | Return all the matches. | |
findall | Return the text of a group of all the matches. | |
split | Split the subject at the matches. | |
sub | Replace the matches. | |
search_character | pass(self) | Search the leftmost match in a character. |
search_string | pass(self) | Search the leftmost match in a string. |
match_character | pass(self) | Match at the start of a character. |
match_string | pass(self) | Match at the start of a string. |
fullmatch_character | pass(self) | Match the whole character. |
fullmatch_string | pass(self) | Match the whole string. |
finditer_character | pass(self) | All the matches in a character. |
finditer_string | pass(self) | All the matches in a string. |
findall_character | pass(self) | Group texts of all the matches in a character. |
findall_string | pass(self) | Group texts of all the matches in a string. |
split_character | pass(self) | Split a character. |
split_string | pass(self) | Split a string. |
sub_character | pass(self) | Replace the matches in a character. |
sub_string | pass(self) | Replace the matches in a string. |
regex_match
The result of a match: whether it was found, and the position and the text of each group.
Components
| Name | Type | Attributes | Description |
|---|---|---|---|
found | logical | True if there is a match. | |
spans | integer | allocatable | First and last byte of each group 0..n; [0, -1] if it did not match. |
texts | type(string) | allocatable | Text of each group 0..n; not allocated if it did not match. |
names | type(string) | allocatable | Name of each group 1..n, null if unnamed. |
Type-Bound Procedures
| Name | Attributes | Description |
|---|---|---|
span | Return the first and last byte of a group. | |
group | Return the text of a group. | |
groups | pass(self) | Return the texts of the groups 1..n. |
span_number | pass(self) | Span of a group by number. |
span_name | pass(self) | Span of a group by name. |
group_number | pass(self) | Text of a group by number. |
group_name | pass(self) | Text of a group by name. |
parser
State of the parser and of the compiler of a pattern.
Components
| Name | Type | Attributes | Description |
|---|---|---|---|
pattern | character(kind=CK, len=:) | allocatable | The pattern. |
ip | integer | Position in the pattern. | |
nocase | logical | Flag i. | |
multiline | logical | Flag m. | |
dotall | logical | Flag s. | |
nnodes | integer | Number of nodes. | |
kind | integer | allocatable | Kind of each node. |
val1 | integer | allocatable | First value of each node. |
val2 | integer | allocatable | Second value of each node. |
val3 | integer | allocatable | Third value of each node. |
child | integer | allocatable | First child of each node. |
sibling | integer | allocatable | Next sibling of each node. |
nranges | integer | Number of ranges. | |
ranges | integer(kind=I4P) | allocatable | Ranges of the classes. |
nclasses | integer | Number of classes. | |
class_first | integer | allocatable | First range of each class. |
class_last | integer | allocatable | Last range of each class. |
class_negated | logical | allocatable | True if the class is negated. |
ngroups | integer | Number of capturing groups. | |
names | type(string) | allocatable | Names of the groups. |
nregs | integer | Number of loop registers. | |
npc | integer | Size of the program. | |
op | integer | allocatable | Instructions. |
arg1 | integer | allocatable | First arguments. |
arg2 | integer | allocatable | Second arguments. |
arg3 | integer | allocatable | Third arguments. |
error | integer | Position of the first error, 0 if none. | |
message | character(len=:) | allocatable | Message of the first error. |
Interfaces
re_search
Overloading of re_search for character and string subjects, character and compiled patterns.
Module procedures: re_search_cc, re_search_cr, re_search_sc, re_search_sr
re_fullmatch
Overloading of re_fullmatch for character and string subjects, character and compiled patterns.
Module procedures: re_fullmatch_cc, re_fullmatch_cr, re_fullmatch_sc, re_fullmatch_sr
re_findall
Overloading of re_findall for character and string subjects, character and compiled patterns.
Module procedures: re_findall_cc, re_findall_cr, re_findall_sc, re_findall_sr
re_split
Overloading of re_split for character and string subjects, character and compiled patterns.
Module procedures: re_split_cc, re_split_cr, re_split_sc, re_split_sr
re_sub
Overloading of re_sub for character and string subjects, character and compiled patterns.
Module procedures: re_sub_cc, re_sub_cr, re_sub_sc, re_sub_sr
Subroutines
compile
Compile a pattern.
flags holds the letters of the flags: i (ASCII case ignored), m (multiline: ^ and $ at the line ends), s (the dot matches LF too); they can also start the pattern, as (?im). On a malformed pattern iostat is the byte position of the error and iomsg says what it is, and the regex is left not compiled; without iostat the program stops with that message.
type(regex) :: re
integer :: iostat
character(len=99) :: iomsg
logical :: test_passed(6)
call re%compile('(\d+)-(\d+)', iostat=iostat)
test_passed(1) = iostat==0.and.re%group_count()==2
call re%compile('a(b', iostat=iostat, iomsg=iomsg)
test_passed(2) = iostat==4.and.trim(iomsg)=='missing ), unterminated group opened at byte 2'
call re%compile('x{2,1}', iostat=iostat)
test_passed(3) = iostat==2
call re%compile('a{1001}', iostat=iostat, iomsg=iomsg)
test_passed(4) = iostat==2.and.trim(iomsg)=='repeat count above 1000'
call re%compile(repeat('(', 300)//repeat(')', 300), iostat=iostat, iomsg=iomsg)
test_passed(5) = iostat==201.and.trim(iomsg)=='groups nested too deep'
call re%compile('(a{1000}){1000}', iostat=iostat, iomsg=iomsg)
test_passed(6) = iostat==1.and.index(iomsg, 'pattern too large')==1.and..not.re%is_compiled()
print '(L1)', all(test_passed)subroutine compile(self, pattern, flags, iostat, iomsg)Arguments
| Name | Type | Intent | Attributes | Description |
|---|---|---|---|---|
self | class(regex) | inout | The regex. | |
pattern | character(len=*) | in | The pattern. | |
flags | character(len=*) | in | optional | Flags: letters i, m, s. |
iostat | integer | out | optional | Byte position of the error, 0 if none. |
iomsg | character(len=*) | inout | optional | Message of the error. |
Call graph
add_thread
Add to a list the threads reached from the instruction pc0 at the position pos, in priority order.
The epsilon closure is followed with an explicit stack, so a long program never overflows the call stack. A negative entry restores a slot when the branch that set it is done.
Attributes: pure
subroutine add_thread(self, subject, stack, mark, caps, list_pc, list_cap, count, gen, pc0, pos)Arguments
| Name | Type | Intent | Attributes | Description |
|---|---|---|---|---|
self | type(regex) | in | The regex. | |
subject | character(len=*) | in | The subject. | |
stack | integer | inout | Stack: (instruction or -slot, value). | |
mark | integer | inout | Generation in which each instruction was added. | |
caps | integer | inout | Slots of the thread being added, restored on exit. | |
list_pc | integer | inout | Instructions of the list. | |
list_cap | integer | inout | Slots of the list. | |
count | integer | inout | Threads in the list. | |
gen | integer | in | Generation of the list. | |
pc0 | integer | in | First instruction. | |
pos | integer | in | Position. |
Call graph
all_matches
Find the matches left to right from the byte start, at most limit of them (0: no limit), as Python's finditer: the search goes on at the end of each match, and after an empty match the next one may not be empty at that position.
Attributes: pure
subroutine all_matches(self, subject, start, limit, matches, n)Arguments
| Name | Type | Intent | Attributes | Description |
|---|---|---|---|---|
self | type(regex) | in | The regex. | |
subject | character(len=*) | in | The subject. | |
start | integer | in | optional | First byte, default 1. |
limit | integer | in | Most matches, 0 if no limit. | |
matches | type(regex_match) | out | allocatable | The matches, the first n used. |
n | integer | out | Number of matches. |
Call graph
parse_template
Parse a replacement template into pieces: a text (group -1) or the text of a group.
Attributes: pure
subroutine parse_template(self, repl, piece_group, piece_text, error, message)Arguments
| Name | Type | Intent | Attributes | Description |
|---|---|---|---|---|
self | type(regex) | in | The regex. | |
repl | character(len=*) | in | Template. | |
piece_group | integer | out | allocatable | Group of each piece, -1 for a text. |
piece_text | type(string) | out | allocatable | Text of each piece. |
error | integer | out | Position of the first error, 0 if none. | |
message | character(len=:) | out | allocatable | Message of the error. |
Call graph
add_piece
Close the text collected so far as a piece, if any, then add the group (if group >= 0) as a piece.
Attributes: pure
subroutine add_piece(piece_group, piece_text, text, group)Arguments
| Name | Type | Intent | Attributes | Description |
|---|---|---|---|---|
piece_group | integer | inout | allocatable | Group of each piece, -1 for a text. |
piece_text | type(string) | inout | allocatable | Text of each piece. |
text | character(len=:) | inout | allocatable | Text collected, emptied. |
group | integer | in | Group, -1 to close the text only. |
Call graph
fail
Record the first error.
Attributes: pure
subroutine fail(p, pos, message)Arguments
| Name | Type | Intent | Attributes | Description |
|---|---|---|---|---|
p | type(parser) | inout | Parser. | |
pos | integer | in | Byte position of the error. | |
message | character(len=*) | in | What is wrong. |
Call graph
set_flag
Set a flag from its letter.
Attributes: pure
subroutine set_flag(p, letter, pos)Arguments
| Name | Type | Intent | Attributes | Description |
|---|---|---|---|---|
p | type(parser) | inout | Parser. | |
letter | character(len=1) | in | Letter of the flag. | |
pos | integer | in | Position of the letter in the pattern, 0 if in the flags argument. |
Call graph
parse_global_flags
Parse the flags (?ims) at the start of the pattern.
Attributes: pure
subroutine parse_global_flags(p)Arguments
| Name | Type | Intent | Attributes | Description |
|---|---|---|---|---|
p | type(parser) | inout | Parser. |
Call graph
new_node
Add a node to the tree.
Attributes: pure
subroutine new_node(p, node, kind, val1, val2, val3)Arguments
| Name | Type | Intent | Attributes | Description |
|---|---|---|---|---|
p | type(parser) | inout | Parser. | |
node | integer | out | The node. | |
kind | integer | in | Kind of node. | |
val1 | integer | in | optional | First value. |
val2 | integer | in | optional | Second value. |
val3 | integer | in | optional | Third value. |
Call graph
add_child
Append a child to a node; last is its last child so far (0 if none), updated.
Attributes: pure
subroutine add_child(p, parent, last, node)Arguments
| Name | Type | Intent | Attributes | Description |
|---|---|---|---|---|
p | type(parser) | inout | Parser. | |
parent | integer | in | Parent node. | |
last | integer | inout | Last child. | |
node | integer | in | New child. |
Call graph
parse_alternation
Parse concatenation ( '|' concatenation )*.
Attributes: pure, recursive
subroutine parse_alternation(p, depth, node)Arguments
| Name | Type | Intent | Attributes | Description |
|---|---|---|---|---|
p | type(parser) | inout | Parser. | |
depth | integer | in | Nesting depth of the groups. | |
node | integer | out | The node. |
Call graph
parse_concatenation
Parse a sequence of repeated atoms, up to |, ) or the end.
Attributes: pure, recursive
subroutine parse_concatenation(p, depth, node)Arguments
| Name | Type | Intent | Attributes | Description |
|---|---|---|---|---|
p | type(parser) | inout | Parser. | |
depth | integer | in | Nesting depth of the groups. | |
node | integer | out | The node. |
Call graph
parse_repeat
Parse an atom and its quantifier, if any: *, +, ?, {m}, {m,}, {,n}, {m,n}, each followed by an optional ? (lazy).
Attributes: pure, recursive
subroutine parse_repeat(p, depth, node)Arguments
| Name | Type | Intent | Attributes | Description |
|---|---|---|---|---|
p | type(parser) | inout | Parser. | |
depth | integer | in | Nesting depth of the groups. | |
node | integer | out | The node. |
Call graph
quantifier
Read the quantifier at pos, if any. A { that does not start {m}, {m,}, {,n}, {m,n} or {,} is a literal.
Attributes: pure
subroutine quantifier(p, pos, is_quantifier, lo, hi, after)Arguments
| Name | Type | Intent | Attributes | Description |
|---|---|---|---|---|
p | type(parser) | in | Parser. | |
pos | integer | in | Position. | |
is_quantifier | logical | out | True if a quantifier is there. | |
lo | integer | out | Minimum count. | |
hi | integer | out | Maximum count, -1 if none. | |
after | integer | out | Position after the quantifier. |
Call graph
read_count
Read decimal digits at j, saturated above MAX_REPEAT + 1; j moves after them.
Attributes: pure
subroutine read_count(text, j, value, has_digits)Arguments
| Name | Type | Intent | Attributes | Description |
|---|---|---|---|---|
text | character(len=*) | in | Text. | |
j | integer | inout | Position. | |
value | integer | out | Value. | |
has_digits | logical | out | True if there was at least one digit. |
Call graph
parse_atom
Parse an atom: a group, a class, the dot, an anchor, an escape or a unit.
Attributes: pure, recursive
subroutine parse_atom(p, depth, node)Arguments
| Name | Type | Intent | Attributes | Description |
|---|---|---|---|---|
p | type(parser) | inout | Parser. | |
depth | integer | in | Nesting depth of the groups. | |
node | integer | out | The node. |
Call graph
new_group
Number a new capturing group.
Attributes: pure
subroutine new_group(p, name, pos, group)Arguments
| Name | Type | Intent | Attributes | Description |
|---|---|---|---|---|
p | type(parser) | inout | Parser. | |
name | character(len=*) | in | Name, empty if unnamed. | |
pos | integer | in | Position, for the errors. | |
group | integer | out | Number of the group. |
Call graph
grow_names
Double the room for the names of the groups; the new ones are not allocated (unnamed).
Attributes: pure
subroutine grow_names(p)Arguments
| Name | Type | Intent | Attributes | Description |
|---|---|---|---|---|
p | type(parser) | inout | Parser. |
Call graph
parse_escape
Parse an escape outside a class.
Attributes: pure
subroutine parse_escape(p, node)Arguments
| Name | Type | Intent | Attributes | Description |
|---|---|---|---|---|
p | type(parser) | inout | Parser. | |
node | integer | out | The node. |
Call graph
escape_code
Parse the escape of a single unit at p%ip (the backslash) and move after it.
Attributes: pure
subroutine escape_code(p, code)Arguments
| Name | Type | Intent | Attributes | Description |
|---|---|---|---|---|
p | type(parser) | inout | Parser. | |
code | integer(kind=I4P) | out | Code of the unit. |
Call graph
new_class
Open a new class.
Attributes: pure
subroutine new_class(p, k)Arguments
| Name | Type | Intent | Attributes | Description |
|---|---|---|---|---|
p | type(parser) | inout | Parser. | |
k | integer | out | The class. |
Call graph
add_range
Add a range of codes to the class being built.
Attributes: pure
subroutine add_range(p, first, last)Arguments
| Name | Type | Intent | Attributes | Description |
|---|---|---|---|---|
p | type(parser) | inout | Parser. | |
first | integer(kind=I4P) | in | First code. | |
last | integer(kind=I4P) | in | Last code. |
Call graph
add_escape_class
Add the ranges of \d, \w, \s to the class being built; for \D, \W, \S the complement if negated is not wanted by the caller (inside brackets), else the plain ranges with negated true.
Attributes: pure
subroutine add_escape_class(p, letter, negated)Arguments
| Name | Type | Intent | Attributes | Description |
|---|---|---|---|---|
p | type(parser) | inout | Parser. | |
letter | character(len=1) | in | d, D, w, W, s, S. | |
negated | logical | out | True for D, W, S. |
Call graph
add_complement
Replace the ranges of the class from the range first on (sorted, disjoint) with their complement in [0, MAX_CODE].
Attributes: pure
subroutine add_complement(p, first)Arguments
| Name | Type | Intent | Attributes | Description |
|---|---|---|---|---|
p | type(parser) | inout | Parser. | |
first | integer | in | First range to complement. |
Call graph
close_class
Finish the class k: with flag i, add the other case of the ASCII letters it holds.
Attributes: pure
subroutine close_class(p, k)Arguments
| Name | Type | Intent | Attributes | Description |
|---|---|---|---|---|
p | type(parser) | inout | Parser. | |
k | integer | in | The class. |
Call graph
parse_class
Parse a class [...]: ^ negates it, a ] first is a literal, a - first or last is a literal, ranges a-z, escapes as outside plus \b (backspace), and the class escapes \d \w \s \D \W \S.
Attributes: pure
subroutine parse_class(p, node)Arguments
| Name | Type | Intent | Attributes | Description |
|---|---|---|---|---|
p | type(parser) | inout | Parser. | |
node | integer | out | The node. |
Call graph
class_item
Parse an item of a class: a unit, an escape or a class escape (whose ranges are added at once).
Attributes: pure
subroutine class_item(p, code, is_set)Arguments
| Name | Type | Intent | Attributes | Description |
|---|---|---|---|---|
p | type(parser) | inout | Parser. | |
code | integer(kind=I4P) | out | Code of the unit. | |
is_set | logical | out | The item was a class escape. |
Call graph
sort_ranges
Sort the ranges of the class k by their first code (insertion sort: classes are small).
Attributes: pure
subroutine sort_ranges(p, k)Arguments
| Name | Type | Intent | Attributes | Description |
|---|---|---|---|---|
p | type(parser) | inout | Parser. | |
k | integer | in | The class. |
Call graph
emit
Append an instruction to the program.
Attributes: pure
subroutine emit(p, op, a1, a2, a3)Arguments
| Name | Type | Intent | Attributes | Description |
|---|---|---|---|---|
p | type(parser) | inout | Parser. | |
op | integer | in | Instruction. | |
a1 | integer | in | optional | First argument. |
a2 | integer | in | optional | Second argument. |
a3 | integer | in | optional | Third argument. |
Call graph
compile_node
Compile a node into the program.
Attributes: pure, recursive
subroutine compile_node(p, node)Arguments
| Name | Type | Intent | Attributes | Description |
|---|---|---|---|---|
p | type(parser) | inout | Parser. | |
node | integer | in | The node. |
Call graph
set_split
Set the targets of a split: the body first if greedy, the exit first if lazy.
Attributes: pure
subroutine set_split(p, pc, body, out, greedy)Arguments
| Name | Type | Intent | Attributes | Description |
|---|---|---|---|---|
p | type(parser) | inout | Parser. | |
pc | integer | in | The split. | |
body | integer | in | The body. | |
out | integer | in | The exit. | |
greedy | logical | in | Greedy. |
Call graph
Functions
is_compiled
Return true if the regex is compiled.
Attributes: elemental
Returns: logical
function is_compiled(self)Arguments
| Name | Type | Intent | Attributes | Description |
|---|---|---|---|---|
self | class(regex) | in | The regex. |
group_count
Return the number of capturing groups.
Attributes: elemental
Returns: integer
function group_count(self) result(n)Arguments
| Name | Type | Intent | Attributes | Description |
|---|---|---|---|---|
self | class(regex) | in | The regex. |
group_index
Return the number of the group named name, 0 if there is none.
Attributes: elemental
Returns: integer
function group_index(self, name) result(n)Arguments
| Name | Type | Intent | Attributes | Description |
|---|---|---|---|---|
self | class(regex) | in | The regex. | |
name | character(len=*) | in | Name of a group. |
Call graph
search_character
Search the leftmost match in the subject, from the byte start (default 1).
@note As Python pattern.search(subject, start): ^ and \A still mean the start of the subject, and \b looks at the byte before start.
type(regex) :: re
type(regex_match) :: m
logical :: test_passed(4)
call re%compile('(?P<key>\w+)\s*=\s*(?P<value>\w*)')
m = re%search('# x = 1, y=two')
test_passed(1) = m%found.and.all(m%span(0) == [3, 7])
test_passed(2) = m%group('key')=='x'.and.m%group(2)=='1'
m = re%search('# x = 1, y=two', start=8)
test_passed(3) = m%group(0)=='y=two'
m = re%search('nothing here')
test_passed(4) = .not.m%found
print '(L1)', all(test_passed)Attributes: pure
Returns: type(regex_match)
function search_character(self, subject, start) result(found)Arguments
| Name | Type | Intent | Attributes | Description |
|---|---|---|---|---|
self | class(regex) | in | The regex. | |
subject | character(len=*) | in | The subject. | |
start | integer | in | optional | First byte of the search, default 1. |
Call graph
search_string
Search the leftmost match in the subject, from the byte start (default 1); see search_character.
@note The doctest is not necessary, this being tested by search_character.
Attributes: pure
Returns: type(regex_match)
function search_string(self, subject, start) result(found)Arguments
| Name | Type | Intent | Attributes | Description |
|---|---|---|---|---|
self | class(regex) | in | The regex. | |
subject | type(string) | in | The subject. | |
start | integer | in | optional | First byte of the search, default 1. |
Call graph
match_character
Match at the byte start (default 1) of the subject only.
type(regex) :: re
type(regex_match) :: m
logical :: test_passed(2)
call re%compile('\d+')
m = re%match('42 and 7')
test_passed(1) = m%group(0)=='42'
m = re%match('x42')
test_passed(2) = .not.m%found
print '(L1)', all(test_passed)Attributes: pure
Returns: type(regex_match)
function match_character(self, subject, start) result(found)Arguments
| Name | Type | Intent | Attributes | Description |
|---|---|---|---|---|
self | class(regex) | in | The regex. | |
subject | character(len=*) | in | The subject. | |
start | integer | in | optional | Byte where the match must start, default 1. |
Call graph
match_string
Match at the byte start (default 1) of the subject only; see match_character.
@note The doctest is not necessary, this being tested by match_character.
Attributes: pure
Returns: type(regex_match)
function match_string(self, subject, start) result(found)Arguments
| Name | Type | Intent | Attributes | Description |
|---|---|---|---|---|
self | class(regex) | in | The regex. | |
subject | type(string) | in | The subject. | |
start | integer | in | optional | Byte where the match must start, default 1. |
Call graph
fullmatch_character
Match the whole subject, from the byte start (default 1) to its end.
type(regex) :: re
type(regex_match) :: m
logical :: test_passed(3)
call re%compile('a|ab')
m = re%fullmatch('ab')
test_passed(1) = m%group(0)=='ab'
m = re%search('ab')
test_passed(2) = m%group(0)=='a'
call re%compile('caf'//char(92)//'u00e9|tea', flags='i')
m = re%fullmatch('CAF'//char(195)//char(169))
test_passed(3) = m%found
print '(L1)', all(test_passed)Attributes: pure
Returns: type(regex_match)
function fullmatch_character(self, subject, start) result(found)Arguments
| Name | Type | Intent | Attributes | Description |
|---|---|---|---|---|
self | class(regex) | in | The regex. | |
subject | character(len=*) | in | The subject. | |
start | integer | in | optional | Byte where the match must start, default 1. |
Call graph
fullmatch_string
Match the whole subject, from the byte start (default 1); see fullmatch_character.
@note The doctest is not necessary, this being tested by fullmatch_character.
Attributes: pure
Returns: type(regex_match)
function fullmatch_string(self, subject, start) result(found)Arguments
| Name | Type | Intent | Attributes | Description |
|---|---|---|---|---|
self | class(regex) | in | The regex. | |
subject | type(string) | in | The subject. | |
start | integer | in | optional | Byte where the match must start, default 1. |
Call graph
finditer_character
Return all the matches, left to right and not overlapping, from the byte start (default 1).
@note As Python finditer: after an empty match the next one may not be empty at the same position, and an empty match is allowed right after a non-empty one.
type(regex) :: re
type(regex_match), allocatable :: m(:)
logical :: test_passed(3)
call re%compile('\d+')
m = re%finditer('a1 b22 c333')
test_passed(1) = size(m)==3.and.m(3)%group(0)=='333'.and.all(m(2)%span(0)==[5, 6])
call re%compile('x*')
m = re%finditer('axb')
test_passed(2) = size(m)==4 ! '' at 1, 'x' at 2, '' at 3 (after a non-empty match), '' at the end
test_passed(3) = all(m(3)%span(0)==[3, 2]).and.all(m(4)%span(0)==[4, 3])
print '(L1)', all(test_passed)Attributes: pure
Returns: type(regex_match)
function finditer_character(self, subject, start) result(matches)Arguments
| Name | Type | Intent | Attributes | Description |
|---|---|---|---|---|
self | class(regex) | in | The regex. | |
subject | character(len=*) | in | The subject. | |
start | integer | in | optional | First byte of the search, default 1. |
Call graph
finditer_string
Return all the matches, left to right; see finditer_character.
@note The doctest is not necessary, this being tested by finditer_character.
Attributes: pure
Returns: type(regex_match)
function finditer_string(self, subject, start) result(matches)Arguments
| Name | Type | Intent | Attributes | Description |
|---|---|---|---|---|
self | class(regex) | in | The regex. | |
subject | type(string) | in | The subject. | |
start | integer | in | optional | First byte of the search, default 1. |
Call graph
findall_character
Return the text of a group of every match, left to right (see finditer_character).
@note The group is by default 1 if the regex has exactly one capturing group, else 0 (the whole match), as Python findall for 0 or 1 group; with more groups Python returns tuples, here one group is chosen with group. A group that did not match gives an empty string.
type(regex) :: re
type(string), allocatable :: t(:)
logical :: test_passed(3)
call re%compile('-?\d+(?:\.\d+)?')
t = re%findall('x=1.5, y=-2, z=30')
test_passed(1) = size(t)==3.and.t(2)=='-2'
call re%compile('(\w+)=')
t = re%findall('x=1.5, y=-2')
test_passed(2) = size(t)==2.and.t(1)=='x'.and.t(2)=='y'
t = re%findall('x=1.5, y=-2', group=0)
test_passed(3) = t(2)=='y='
print '(L1)', all(test_passed)Attributes: pure
Returns: type(string)
function findall_character(self, subject, group) result(texts)Arguments
| Name | Type | Intent | Attributes | Description |
|---|---|---|---|---|
self | class(regex) | in | The regex. | |
subject | character(len=*) | in | The subject. | |
group | integer | in | optional | Group, default 1 if there is one group, else 0. |
Call graph
findall_string
Return the text of a group of every match; see findall_character.
@note The doctest is not necessary, this being tested by findall_character.
Attributes: pure
Returns: type(string)
function findall_string(self, subject, group) result(texts)Arguments
| Name | Type | Intent | Attributes | Description |
|---|---|---|---|---|
self | class(regex) | in | The regex. | |
subject | type(string) | in | The subject. | |
group | integer | in | optional | Group, default 1 if there is one group, else 0. |
Call graph
split_character
Return the subject split at the matches, at most maxsplit times (default, or 0: no limit).
@note As Python re.split: the texts of the groups of each match are inserted between the pieces (a group that did not match is a not allocated string), and an empty match splits too.
type(regex) :: re
type(string), allocatable :: p(:)
logical :: test_passed(3)
call re%compile('\s*[,;]\s*')
p = re%split('a , b;c ; d')
test_passed(1) = size(p)==4.and.p(4)=='d'
p = re%split('a , b;c ; d', maxsplit=1)
test_passed(2) = size(p)==2.and.p(2)=='b;c ; d'
call re%compile('([,;])')
p = re%split('a,b;c')
test_passed(3) = size(p)==5.and.p(2)==','.and.p(4)==';'
print '(L1)', all(test_passed)Attributes: pure
Returns: type(string)
function split_character(self, subject, maxsplit) result(pieces)Arguments
| Name | Type | Intent | Attributes | Description |
|---|---|---|---|---|
self | class(regex) | in | The regex. | |
subject | character(len=*) | in | The subject. | |
maxsplit | integer | in | optional | Most splits, default 0: no limit. |
Call graph
split_string
Return the subject split at the matches; see split_character.
@note The doctest is not necessary, this being tested by split_character.
Attributes: pure
Returns: type(string)
function split_string(self, subject, maxsplit) result(pieces)Arguments
| Name | Type | Intent | Attributes | Description |
|---|---|---|---|---|
self | class(regex) | in | The regex. | |
subject | type(string) | in | The subject. | |
maxsplit | integer | in | optional | Most splits, default 0: no limit. |
Call graph
sub_character
Return the subject with the matches replaced by the template repl, at most count of them (default, or 0: all).
@note In the template \1..\99 and \g<n> are the text of a group, \g<name> of a named group, \g<0> the whole match; a group that did not match gives an empty text. \\ \n \t \r \f \v \a \b are escapes, a backslash before any other character that is not an ASCII letter or a digit stays. nsub returns the number of replacements (Python subn). A malformed template (an unknown escape, a group that does not exist) sets iostat to the byte position of the error in repl and returns the subject unchanged; without iostat the program stops.
type(regex) :: re
type(string) :: s
integer :: n
logical :: test_passed(3)
call re%compile('(?P<y>\d{4})-(?P<m>\d\d)-(?P<d>\d\d)')
s = re%sub('\g<d>/\g<m>/\g<y>', 'from 2026-10-30 to 2026-11-02', nsub=n)
test_passed(1) = s=='from 30/10/2026 to 02/11/2026'.and.n==2
call re%compile('\s+')
s = re%sub(' ', ' too many spaces ', count=2)
test_passed(2) = s==' too many spaces '
s = re%sub('\q', 'a b', iostat=n)
test_passed(3) = n==1.and.s=='a b'
print '(L1)', all(test_passed)Returns: type(string)
function sub_character(self, repl, subject, count, nsub, iostat, iomsg) result(replaced)Arguments
| Name | Type | Intent | Attributes | Description |
|---|---|---|---|---|
self | class(regex) | in | The regex. | |
repl | character(len=*) | in | Template of the replacement. | |
subject | character(len=*) | in | The subject. | |
count | integer | in | optional | Most replacements, default 0: all. |
nsub | integer | out | optional | Number of replacements. |
iostat | integer | out | optional | Byte position of an error in repl, 0 if none. |
iomsg | character(len=*) | inout | optional | Message of the error. |
Call graph
sub_string
Return the subject with the matches replaced; see sub_character.
@note The doctest is not necessary, this being tested by sub_character.
Returns: type(string)
function sub_string(self, repl, subject, count, nsub, iostat, iomsg) result(replaced)Arguments
| Name | Type | Intent | Attributes | Description |
|---|---|---|---|---|
self | class(regex) | in | The regex. | |
repl | character(len=*) | in | Template of the replacement. | |
subject | type(string) | in | The subject. | |
count | integer | in | optional | Most replacements, default 0: all. |
nsub | integer | out | optional | Number of replacements. |
iostat | integer | out | optional | Byte position of an error in repl, 0 if none. |
iomsg | character(len=*) | inout | optional | Message of the error. |
Call graph
span_number
Return the first and the last byte of a group (0: the whole match); [0, -1] if the group did not match.
@note An empty group at byte p gives [p, p-1], so subject(span(1):span(2)) is always its text.
type(regex) :: re
type(regex_match) :: m
logical :: test_passed(3)
call re%compile('(a)|(b)|(x*)')
m = re%search('b')
test_passed(1) = all(m%span(0) == [1, 1]).and.all(m%span(2) == [1, 1])
test_passed(2) = all(m%span(1) == [0, -1])
m = re%search('c')
test_passed(3) = all(m%span(3) == [1, 0])
print '(L1)', all(test_passed)Attributes: pure
Returns: integer
function span_number(self, group) result(span)Arguments
| Name | Type | Intent | Attributes | Description |
|---|---|---|---|---|
self | class(regex_match) | in | The match. | |
group | integer | in | Number of the group. |
Call graph
span_name
Return the first and the last byte of a named group; [0, -1] if it did not match or there is no such group.
@note The doctest is not necessary, this being tested by search_character.
Attributes: pure
Returns: integer
function span_name(self, group) result(span)Arguments
| Name | Type | Intent | Attributes | Description |
|---|---|---|---|---|
self | class(regex_match) | in | The match. | |
group | character(len=*) | in | Name of the group. |
Call graph
group_number
Return the text of a group (0: the whole match); a not allocated string if the group did not match.
type(regex) :: re
type(regex_match) :: m
type(string) :: g
logical :: test_passed(2)
call re%compile('(\d+)(?:\.(\d+))?')
m = re%search('v12')
test_passed(1) = m%group(1)=='12'
g = m%group(2)
test_passed(2) = .not.g%is_allocated()
print '(L1)', all(test_passed)Attributes: pure
Returns: type(string)
function group_number(self, group) result(text)Arguments
| Name | Type | Intent | Attributes | Description |
|---|---|---|---|---|
self | class(regex_match) | in | The match. | |
group | integer | in | Number of the group. |
Call graph
group_name
Return the text of a named group; a not allocated string if it did not match or there is no such group.
@note The doctest is not necessary, this being tested by search_character.
Attributes: pure
Returns: type(string)
function group_name(self, group) result(text)Arguments
| Name | Type | Intent | Attributes | Description |
|---|---|---|---|---|
self | class(regex_match) | in | The match. | |
group | character(len=*) | in | Name of the group. |
Call graph
groups
Return the texts of the groups 1..n; a group that did not match is a not allocated string.
type(regex) :: re
type(regex_match) :: m
type(string), allocatable :: g(:)
call re%compile('(\w+)@(\w+)\.(\w+)')
m = re%search('mail: ann@example.org')
g = m%groups()
print '(L1)', size(g)==3.and.g(1)=='ann'.and.g(3)=='org'Attributes: pure
Returns: type(string)
function groups(self) result(texts)Arguments
| Name | Type | Intent | Attributes | Description |
|---|---|---|---|---|
self | class(regex_match) | in | The match. |
name_index
Return the number of the group named name in a match, -1 if there is none.
Attributes: pure
Returns: integer
function name_index(self, name) result(n)Arguments
| Name | Type | Intent | Attributes | Description |
|---|---|---|---|---|
self | type(regex_match) | in | The match. | |
name | character(len=*) | in | Name of a group. |
Call graph
run
Run the Pike VM on the subject from the byte start.
anchored: the match must start at start; full: it must end at the end of the subject; advance: an empty match at start is not accepted (the search after an empty match, as Python's finditer, sub and split do).
Attributes: pure
Returns: type(regex_match)
function run(self, subject, start, anchored, full, advance) result(found)Arguments
| Name | Type | Intent | Attributes | Description |
|---|---|---|---|---|
self | type(regex) | in | The regex. | |
subject | character(len=*) | in | The subject. | |
start | integer | in | optional | First byte of the search, default 1. |
anchored | logical | in | The match must start at start. | |
full | logical | in | The match must end at the end of the subject. | |
advance | logical | in | No empty match at start. |
Call graph
assertion
Return true if the assertion holds at the position pos of the subject.
Attributes: pure
Returns: logical
function assertion(kind, subject, pos) result(holds)Arguments
| Name | Type | Intent | Attributes | Description |
|---|---|---|---|---|
kind | integer | in | Kind of assertion. | |
subject | character(len=*) | in | The subject. | |
pos | integer | in | Position, 1 to len(subject) + 1. |
Call graph
is_word
Return true if the byte at pos is an ASCII word character, letter, digit or underscore (false outside).
Attributes: pure
Returns: logical
function is_word(subject, pos) result(word)Arguments
| Name | Type | Intent | Attributes | Description |
|---|---|---|---|---|
subject | character(len=*) | in | The subject. | |
pos | integer | in | Position. |
Call graph
fold
Return the code with the ASCII uppercase letters lowercased.
Attributes: elemental
Returns: integer(kind=I4P)
function fold(code) result(folded)Arguments
| Name | Type | Intent | Attributes | Description |
|---|---|---|---|---|
code | integer(kind=I4P) | in | Code of a unit. |
Call graph
in_class
Return true if the code belongs to the class k.
Attributes: pure
Returns: logical
function in_class(self, k, code) result(inside)Arguments
| Name | Type | Intent | Attributes | Description |
|---|---|---|---|---|
self | type(regex) | in | The regex. | |
k | integer | in | Class. | |
code | integer(kind=I4P) | in | Code of a unit. |
Call graph
to_int
Return the value of decimal digits, saturated above MAX_GROUPS + 1.
Attributes: pure
Returns: integer
function to_int(digits) result(value)Arguments
| Name | Type | Intent | Attributes | Description |
|---|---|---|---|---|
digits | character(len=*) | in | Digits. |
Call graph
re_search_cc
Search the leftmost match of a pattern in a subject (see search_character).
@note A character pattern is compiled at each call (a malformed one stops the program): compile it once with compile and pass the regex to repeat the search.
type(regex_match) :: m
logical :: test_passed(2)
m = re_search('key = 42', '(\w+)\s*=\s*(\d+)')
test_passed(1) = m%group(1)=='key'.and.m%group(2)=='42'
m = re_search('KEY=1', 'key=(\d)', flags='i')
test_passed(2) = m%group(1)=='1'
print '(L1)', all(test_passed)Returns: type(regex_match)
function re_search_cc(subject, pattern, flags, start) result(found)Arguments
| Name | Type | Intent | Attributes | Description |
|---|---|---|---|---|
subject | character(len=*) | in | The subject. | |
pattern | character(len=*) | in | The pattern. | |
flags | character(len=*) | in | optional | Flags: letters i, m, s. |
start | integer | in | optional | First byte of the search, default 1. |
Call graph
re_search_cr
Search the leftmost match of a pattern in a subject (see search_character).
@note The doctest is not necessary, this being tested by re_search_cc.
Returns: type(regex_match)
function re_search_cr(subject, pattern, start) result(found)Arguments
| Name | Type | Intent | Attributes | Description |
|---|---|---|---|---|
subject | character(len=*) | in | The subject. | |
pattern | type(regex) | in | The compiled pattern. | |
start | integer | in | optional | First byte of the search, default 1. |
Call graph
re_search_sc
Search the leftmost match of a pattern in a subject (see search_character).
@note The doctest is not necessary, this being tested by re_search_cc.
Returns: type(regex_match)
function re_search_sc(subject, pattern, flags, start) result(found)Arguments
| Name | Type | Intent | Attributes | Description |
|---|---|---|---|---|
subject | type(string) | in | The subject. | |
pattern | character(len=*) | in | The pattern. | |
flags | character(len=*) | in | optional | Flags: letters i, m, s. |
start | integer | in | optional | First byte of the search, default 1. |
Call graph
re_search_sr
Search the leftmost match of a pattern in a subject (see search_character).
@note The doctest is not necessary, this being tested by re_search_cc.
Returns: type(regex_match)
function re_search_sr(subject, pattern, start) result(found)Arguments
| Name | Type | Intent | Attributes | Description |
|---|---|---|---|---|
subject | type(string) | in | The subject. | |
pattern | type(regex) | in | The compiled pattern. | |
start | integer | in | optional | First byte of the search, default 1. |
Call graph
re_fullmatch_cc
Match a pattern against a whole subject (see fullmatch_character).
@note A character pattern is compiled at each call (a malformed one stops the program): compile it once with compile and pass the regex to repeat the search.
logical :: test_passed(2)
type(regex_match) :: m
m = re_fullmatch('2026-10-30', '\d{4}-\d\d-\d\d')
test_passed(1) = m%found
m = re_fullmatch('2026-10-30 ', '\d{4}-\d\d-\d\d')
test_passed(2) = .not.m%found
print '(L1)', all(test_passed)Returns: type(regex_match)
function re_fullmatch_cc(subject, pattern, flags) result(found)Arguments
| Name | Type | Intent | Attributes | Description |
|---|---|---|---|---|
subject | character(len=*) | in | The subject. | |
pattern | character(len=*) | in | The pattern. | |
flags | character(len=*) | in | optional | Flags: letters i, m, s. |
Call graph
re_fullmatch_cr
Match a pattern against a whole subject (see fullmatch_character).
@note The doctest is not necessary, this being tested by re_fullmatch_cc.
Returns: type(regex_match)
function re_fullmatch_cr(subject, pattern) result(found)Arguments
| Name | Type | Intent | Attributes | Description |
|---|---|---|---|---|
subject | character(len=*) | in | The subject. | |
pattern | type(regex) | in | The compiled pattern. |
Call graph
re_fullmatch_sc
Match a pattern against a whole subject (see fullmatch_character).
@note The doctest is not necessary, this being tested by re_fullmatch_cc.
Returns: type(regex_match)
function re_fullmatch_sc(subject, pattern, flags) result(found)Arguments
| Name | Type | Intent | Attributes | Description |
|---|---|---|---|---|
subject | type(string) | in | The subject. | |
pattern | character(len=*) | in | The pattern. | |
flags | character(len=*) | in | optional | Flags: letters i, m, s. |
Call graph
re_fullmatch_sr
Match a pattern against a whole subject (see fullmatch_character).
@note The doctest is not necessary, this being tested by re_fullmatch_cc.
Returns: type(regex_match)
function re_fullmatch_sr(subject, pattern) result(found)Arguments
| Name | Type | Intent | Attributes | Description |
|---|---|---|---|---|
subject | type(string) | in | The subject. | |
pattern | type(regex) | in | The compiled pattern. |
Call graph
re_findall_cc
Return the text of a group of every match of a pattern in a subject (see findall_character).
@note A character pattern is compiled at each call (a malformed one stops the program): compile it once with compile and pass the regex to repeat the search.
type(string), allocatable :: words(:)
words = re_findall('one, two;three', '\w+')
print '(L1)', size(words)==3.and.words(3)=='three'Returns: type(string)
function re_findall_cc(subject, pattern, flags, group) result(found)Arguments
| Name | Type | Intent | Attributes | Description |
|---|---|---|---|---|
subject | character(len=*) | in | The subject. | |
pattern | character(len=*) | in | The pattern. | |
flags | character(len=*) | in | optional | Flags: letters i, m, s. |
group | integer | in | optional | Group, default 1 if there is one group, else 0. |
Call graph
re_findall_cr
Return the text of a group of every match of a pattern in a subject (see findall_character).
@note The doctest is not necessary, this being tested by re_findall_cc.
Returns: type(string)
function re_findall_cr(subject, pattern, group) result(found)Arguments
| Name | Type | Intent | Attributes | Description |
|---|---|---|---|---|
subject | character(len=*) | in | The subject. | |
pattern | type(regex) | in | The compiled pattern. | |
group | integer | in | optional | Group, default 1 if there is one group, else 0. |
Call graph
re_findall_sc
Return the text of a group of every match of a pattern in a subject (see findall_character).
@note The doctest is not necessary, this being tested by re_findall_cc.
Returns: type(string)
function re_findall_sc(subject, pattern, flags, group) result(found)Arguments
| Name | Type | Intent | Attributes | Description |
|---|---|---|---|---|
subject | type(string) | in | The subject. | |
pattern | character(len=*) | in | The pattern. | |
flags | character(len=*) | in | optional | Flags: letters i, m, s. |
group | integer | in | optional | Group, default 1 if there is one group, else 0. |
Call graph
re_findall_sr
Return the text of a group of every match of a pattern in a subject (see findall_character).
@note The doctest is not necessary, this being tested by re_findall_cc.
Returns: type(string)
function re_findall_sr(subject, pattern, group) result(found)Arguments
| Name | Type | Intent | Attributes | Description |
|---|---|---|---|---|
subject | type(string) | in | The subject. | |
pattern | type(regex) | in | The compiled pattern. | |
group | integer | in | optional | Group, default 1 if there is one group, else 0. |
Call graph
re_split_cc
Split a subject at the matches of a pattern (see split_character).
@note A character pattern is compiled at each call (a malformed one stops the program): compile it once with compile and pass the regex to repeat the search.
type(string), allocatable :: fields(:)
fields = re_split('a1b22c', '\d+')
print '(L1)', size(fields)==3.and.fields(2)=='b'Returns: type(string)
function re_split_cc(subject, pattern, flags, maxsplit) result(found)Arguments
| Name | Type | Intent | Attributes | Description |
|---|---|---|---|---|
subject | character(len=*) | in | The subject. | |
pattern | character(len=*) | in | The pattern. | |
flags | character(len=*) | in | optional | Flags: letters i, m, s. |
maxsplit | integer | in | optional | Most splits, default 0: no limit. |
Call graph
re_split_cr
Split a subject at the matches of a pattern (see split_character).
@note The doctest is not necessary, this being tested by re_split_cc.
Returns: type(string)
function re_split_cr(subject, pattern, maxsplit) result(found)Arguments
| Name | Type | Intent | Attributes | Description |
|---|---|---|---|---|
subject | character(len=*) | in | The subject. | |
pattern | type(regex) | in | The compiled pattern. | |
maxsplit | integer | in | optional | Most splits, default 0: no limit. |
Call graph
re_split_sc
Split a subject at the matches of a pattern (see split_character).
@note The doctest is not necessary, this being tested by re_split_cc.
Returns: type(string)
function re_split_sc(subject, pattern, flags, maxsplit) result(found)Arguments
| Name | Type | Intent | Attributes | Description |
|---|---|---|---|---|
subject | type(string) | in | The subject. | |
pattern | character(len=*) | in | The pattern. | |
flags | character(len=*) | in | optional | Flags: letters i, m, s. |
maxsplit | integer | in | optional | Most splits, default 0: no limit. |
Call graph
re_split_sr
Split a subject at the matches of a pattern (see split_character).
@note The doctest is not necessary, this being tested by re_split_cc.
Returns: type(string)
function re_split_sr(subject, pattern, maxsplit) result(found)Arguments
| Name | Type | Intent | Attributes | Description |
|---|---|---|---|---|
subject | type(string) | in | The subject. | |
pattern | type(regex) | in | The compiled pattern. | |
maxsplit | integer | in | optional | Most splits, default 0: no limit. |
Call graph
re_sub_cc
Return a subject with the matches of a pattern replaced by a template (see sub_character).
@note A character pattern is compiled at each call (a malformed one stops the program): compile it once with compile and pass the regex to repeat the search.
type(string) :: s
s = re_sub('x=1, y=22', '(\w)=(\d+)', '\2=\1')
print '(L1)', s=='1=x, 22=y'Returns: type(string)
function re_sub_cc(subject, pattern, repl, flags, count) result(found)Arguments
| Name | Type | Intent | Attributes | Description |
|---|---|---|---|---|
subject | character(len=*) | in | The subject. | |
pattern | character(len=*) | in | The pattern. | |
repl | character(len=*) | in | Template of the replacement (see sub_character). | |
flags | character(len=*) | in | optional | Flags: letters i, m, s. |
count | integer | in | optional | Most replacements, default 0: all. |
Call graph
re_sub_cr
Return a subject with the matches of a pattern replaced by a template (see sub_character).
@note The doctest is not necessary, this being tested by re_sub_cc.
Returns: type(string)
function re_sub_cr(subject, pattern, repl, count) result(found)Arguments
| Name | Type | Intent | Attributes | Description |
|---|---|---|---|---|
subject | character(len=*) | in | The subject. | |
pattern | type(regex) | in | The compiled pattern. | |
repl | character(len=*) | in | Template of the replacement (see sub_character). | |
count | integer | in | optional | Most replacements, default 0: all. |
Call graph
re_sub_sc
Return a subject with the matches of a pattern replaced by a template (see sub_character).
@note The doctest is not necessary, this being tested by re_sub_cc.
Returns: type(string)
function re_sub_sc(subject, pattern, repl, flags, count) result(found)Arguments
| Name | Type | Intent | Attributes | Description |
|---|---|---|---|---|
subject | type(string) | in | The subject. | |
pattern | character(len=*) | in | The pattern. | |
repl | character(len=*) | in | Template of the replacement (see sub_character). | |
flags | character(len=*) | in | optional | Flags: letters i, m, s. |
count | integer | in | optional | Most replacements, default 0: all. |
Call graph
re_sub_sr
Return a subject with the matches of a pattern replaced by a template (see sub_character).
@note The doctest is not necessary, this being tested by re_sub_cc.
Returns: type(string)
function re_sub_sr(subject, pattern, repl, count) result(found)Arguments
| Name | Type | Intent | Attributes | Description |
|---|---|---|---|---|
subject | type(string) | in | The subject. | |
pattern | type(regex) | in | The compiled pattern. | |
repl | character(len=*) | in | Template of the replacement (see sub_character). | |
count | integer | in | optional | Most replacements, default 0: all. |
Call graph
is_identifier
Return true if the name is an ASCII identifier: a letter or underscore, then letters, digits, underscores.
Attributes: pure
Returns: logical
function is_identifier(name) result(ok)Arguments
| Name | Type | Intent | Attributes | Description |
|---|---|---|---|---|
name | character(len=*) | in | Name. |
Call graph
hex_value
Return the value of exactly digits hexadecimal digits at first, -1 if they are not there.
Attributes: pure
Returns: integer(kind=I4P)
function hex_value(text, first, digits) result(value)Arguments
| Name | Type | Intent | Attributes | Description |
|---|---|---|---|---|
text | character(len=*) | in | Text. | |
first | integer | in | Position of the first digit. | |
digits | integer | in | Number of digits. |
Call graph
nullable
Return true if the node can match the empty string.
Attributes: pure, recursive
Returns: logical
function nullable(p, node) result(empty)Arguments
| Name | Type | Intent | Attributes | Description |
|---|---|---|---|---|
p | type(parser) | in | Parser. | |
node | integer | in | The node. |
Call graph
itoa
Return an integer as text.
Attributes: pure
Returns: character(len=:)
function itoa(n) result(text)Arguments
| Name | Type | Intent | Attributes | Description |
|---|---|---|---|---|
n | integer | in | Integer. |
Call graph