Regex
stdlib::regex é um motor de expressões regulares estilo PCRE, escrito em Glide puro, construído sobre uma VM de bytecode com retrocesso. Você compila um padrão em um *Regex, e então testa, busca, captura, substitui ou divide strings com ele. Os padrões operam sobre bytes brutos.
Importação
import stdlib::regex::*;
Visão geral
| Item | Tipo | Resumo |
|---|---|---|
Regex |
struct | Um padrão compilado (pattern, flags, n_groups são pub). |
Match |
struct | Uma correspondência e seus spans de captura (input, start, end são pub). |
CharClass |
struct | Um conjunto de intervalos de bytes inclusivos, opcionalmente negado. |
Regex::compile / compile_with |
fn | Constrói um *Regex (retorna !*Regex). |
matches / matches_full |
method | Teste booleano (substring / string inteira). |
find / find_at / find_all |
method | Localiza correspondências. |
replace / replace_all / replace_with |
method | Substitui correspondências. |
split |
method | Divide nas correspondências. |
full / group / group_opt / named / named_opt / n_groups |
method | Lê um *Match. |
regex_matches / regex_find / regex_replace_all |
fn | Utilitários de uso único (compilam a cada chamada). |
RxNode / RxParser / RxCompiler |
struct | AST/parser/compilador internos (exportados, sem API estável). |
RX_* |
const | Constantes de opcode / flag / AST / tipo de asserção / limite. |
Compilando padrões
Um padrão é compilado uma vez em um *Regex e reutilizado em todas as operações. A compilação analisa o padrão, reporta erros de sintaxe como o err do !*Regex, e produz bytecode para a VM. A correspondência inteira é envolvida em um grupo 0 implícito, portanto start/end/full() estão sempre disponíveis.
Regex::compile / Regex::compile_with
| Função | Assinatura | Descrição |
|---|---|---|
compile |
fn compile(pattern: string) -> !*Regex |
Compila sem flags. |
compile_with |
fn compile_with(pattern: string, flag_str: string) -> !*Regex |
Compila com uma string de flags (qualquer subconjunto de imsxU). |
import stdlib::regex::*;
fn main() -> i32 {
let r: !*Regex = Regex::compile("(\\d+)-(\\d+)");
if !r.ok {
println!("bad pattern:", r.err);
return 1;
}
let re: *Regex = r.val;
if re.matches("phone: 555-1234") {
println!("hit");
}
return 0;
}
compile_with converte cada caractere de flag em um bit de flag; um caractere desconhecido retorna err("unknown flag in flag string"). A compilação também rejeita padrões malformados (err("expected ')'"), "unterminated character class", "trailing characters in pattern", entre outros).
// Insensível a maiúsculas (i) + multilinha (m).
let r: !*Regex = Regex::compile_with("^err", "im");
import stdlib::regex::*;
fn main() -> i32 {
// Um padrão malformado aparece em .err.
let bad: !*Regex = Regex::compile("(unclosed");
if !bad.ok { println!("err:", bad.err); } // expected ')'
// Flag desconhecida.
let bf: !*Regex = Regex::compile_with("x", "q");
if !bf.ok { println!("flagerr:", bf.err); } // unknown flag in flag string
return 0;
}
A struct Regex
pub struct Regex {
pub pattern: string, // o padrão-fonte original
pub flags: i32, // bits de flag resolvidos (veja RX_FLAG_*)
pub n_groups: i32, // número de grupos de captura (exclui o grupo 0)
// ... bytecode/classes/tabela de nomes internos
}
Os três campos pub são metadados somente-leitura que você pode inspecionar após a compilação. flags reflete quaisquer flags resolvidas durante o parsing, incluindo configurações no estilo (?i) inline no nível superior.
import stdlib::regex::*;
fn main() -> i32 {
let re: *Regex = Regex::compile("(?<a>\\d)(?<b>\\d)").val;
println!("pattern", re.pattern); // (?<a>\d)(?<b>\d)
println!("flags", re.flags); // 0
println!("n_groups", re.n_groups); // 2
return 0;
}
Testando uma correspondência
| Método | Assinatura | Descrição |
|---|---|---|
matches |
fn matches(self: *Regex, s: string) -> bool |
true se qualquer substring corresponder. |
matches_full |
fn matches_full(self: *Regex, s: string) -> bool |
true somente se o padrão corresponder à string inteira. |
import stdlib::regex::*;
fn main() -> i32 {
let re: *Regex = Regex::compile("\\d+").val;
if re.matches("hi 42 there") { println!("matches substring"); } // true
if !re.matches("nothing") { println!("no digits"); } // true
let rf: *Regex = Regex::compile("[a-z]+").val;
if rf.matches_full("hello") { println!("full ok"); } // true
if !rf.matches_full("hello world") { println!("full no"); } // espaço/'world' sem correspondência
return 0;
}
matches equivale a find(s).has. matches_full é bem-sucedido apenas quando a primeira correspondência começa no offset 0 e termina em s.len() — ele não ancora o padrão, então uma correspondência mais curta à esquerda pode fazê-lo retornar false mesmo quando existe uma correspondência de comprimento total. Ancore explicitamente com ^...$ (ou \A...\z) se precisar disso.
Buscando e encontrando
| Método | Assinatura | Descrição |
|---|---|---|
find |
fn find(self: *Regex, s: string) -> ?*Match |
Primeira correspondência, ou none(). |
find_at |
fn find_at(self: *Regex, s: string, from: i32) -> ?*Match |
Primeira correspondência a partir do offset de byte from. |
find_all |
fn find_all(self: *Regex, s: string) -> *Vector<*Match> |
Todas as correspondências sem sobreposição (correspondências vazias avançam um byte). |
import stdlib::regex::*;
fn main() -> i32 {
let re: *Regex = Regex::compile("\\d+").val;
// find_all: toda correspondência sem sobreposição, com spans.
let all: *Vector<*Match> = re.find_all("a12 b3 c456");
for let i: i32 = 0; i < all.len(); i++ {
let m: *Match = all.get(i);
println!("match", i, m.full(), m.start, m.end);
}
// find_at: inicia a busca em um offset.
match re.find_at("a12 b3", 3) {
some(m) => println!("from 3:", m.full(), m.start), // 3 no offset 4
none() => println!("none"),
}
// find: sem correspondência -> none().
match re.find("no digits here") {
some(m) => println!("found", m.full()),
none() => println!("no match"),
}
return 0;
}
find equivale a find_at(s, 0). Ambos percorrem para frente a partir do offset inicial, testando a VM em cada posição de byte (a correspondência mais à esquerda vence). find_all chama find_at repetidamente, avançando além de cada correspondência; uma correspondência de largura zero avança um byte para que o laço termine.
O resultado Match e os grupos de captura
Um *Match descreve uma correspondência e seus grupos de captura. O grupo 0 é a correspondência inteira; os grupos 1..n são as capturas entre parênteses, em ordem.
pub struct Match {
pub input: string, // a string que foi pesquisada
pub start: i32, // offset de byte do início da correspondência
pub end: i32, // offset de byte logo após o fim da correspondência
// ... spans de captura + tabela de nomes
}
| Método | Assinatura | Descrição |
|---|---|---|
full |
fn full(self: *Match) -> string |
A substring correspondida completa (igual a group(0)). |
group |
fn group(self: *Match, i: i32) -> string |
Grupo de captura i (0 = correspondência completa); "" para ausente/não capturado. |
group_opt |
fn group_opt(self: *Match, i: i32) -> ?string |
some se o grupo i participou, caso contrário none(). |
named |
fn named(self: *Match, name: string) -> string |
Busca por grupo de captura nomeado; "" se ausente. |
named_opt |
fn named_opt(self: *Match, name: string) -> ?string |
some se o grupo nomeado participou, caso contrário none(). |
n_groups |
fn n_groups(self: *Match) -> i32 |
Número de grupos de captura (excluindo o grupo 0). |
import stdlib::regex::*;
fn main() -> i32 {
let re: *Regex = Regex::compile("(?<year>\\d{4})-(?<month>\\d{2})").val;
match re.find("date 2026-05 end") {
some(m) => {
println!("full:", m.group(0), m.full()); // 2026-05 2026-05
println!("g1:", m.group(1), "g2:", m.group(2)); // 2026 05
println!("year:", m.named("year"), m.named("month"));
println!("groups:", m.n_groups()); // 2
println!("span:", m.start, m.end);
println!("input:", m.input);
}
none() => println!("no match"),
}
return 0;
}
import stdlib::regex::*;
fn main() -> i32 {
// (b)? não participou ao corresponder apenas "a".
let re: *Regex = Regex::compile("(a)(b)?").val;
match re.find("a") {
some(m) => {
let g2: ?string = m.group_opt(2);
if g2.has { println!("g2 present"); } else { println!("g2 missing"); }
println!("g1", m.group(1)); // a
}
none() => println!("no match"),
}
// (x*) participou mas capturou a string vazia.
let re2: *Regex = Regex::compile("(a)(x*)").val;
match re2.find("a") {
some(m) => {
let g2: ?string = m.group_opt(2);
if g2.has { println!("g2 empty-but-present:", g2.val.len()); } // 0
}
none() => {}
}
return 0;
}
Substituindo
| Método | Assinatura | Descrição |
|---|---|---|
replace |
fn replace(self: *Regex, s: string, repl: string) -> string |
Substitui a primeira correspondência. |
replace_all |
fn replace_all(self: *Regex, s: string, repl: string) -> string |
Substitui todas as correspondências sem sobreposição. |
replace_with |
fn replace_with(self: *Regex, s: string, f: fn(*Match) -> string) -> string |
Substitui cada correspondência pelo resultado de f(match). |
A string de substituição (replace / replace_all) suporta retrorreferências e um escape para o $ literal:
| Token | Expande para |
|---|---|
$0 .. $9 |
O grupo de captura correspondente ($0 = correspondência completa). |
${name} |
O grupo de captura nomeado name. |
$$ |
Um $ literal. |
Os tokens numerados e $$ são fáceis de escrever como literais de string Glide:
import stdlib::regex::*;
fn main() -> i32 {
// $$ escapa um '$' literal; $1 é o primeiro grupo.
let price: *Regex = Regex::compile("(\\d+)").val;
println!(price.replace_all("a5 b6", "$$$1")); // a$5 b$6
// Reordena grupos.
let pair: *Regex = Regex::compile("(\\w+)=(\\w+)").val;
println!(pair.replace("k=v rest", "$2:$1")); // v:k rest
// $0 = correspondência inteira. replace toca apenas o primeiro resultado.
let w: *Regex = Regex::compile("\\w+").val;
println!(w.replace("hi there", "[$0]")); // [hi] there
return 0;
}
import stdlib::regex::*;
fn main() -> i32 {
let date: *Regex =
Regex::compile("(?<y>\\d{4})-(?<m>\\d{2})-(?<d>\\d{2})").val;
let d: string = "$";
let repl: string =
d.concat("{d}/").concat(d).concat("{m}/").concat(d).concat("{y}");
println!(date.replace("on 2026-05-30 ok", repl)); // on 30/05/2026 ok
return 0;
}
Os grupos numerados ($1) e $$ não têm esse conflito. Se a substituição por nome for trabalhosa, prefira replace_with e leia m.named(...) no callback.
replace_with chama sua função para cada correspondência e substitui pela string retornada de forma literal (sem expansão de $):
import stdlib::regex::*;
fn mask(m: *Match) -> string {
let n: i32 = m.full().len();
let mut s: string = "";
for let i: i32 = 0; i < n; i++ { s = s.concat("*"); }
return s;
}
fn main() -> i32 {
let digits: *Regex = Regex::compile("\\d+").val;
println!(digits.replace_with("card 4242 9999", mask)); // card **** ****
return 0;
}
Se não houver correspondência, replace/replace_all/replace_with retornam a string de entrada inalterada.
Dividindo
split
fn split(self: *Regex, s: string) -> *Vector<string>
Divide s em cada correspondência sem sobreposição do regex, retornando os pedaços entre as correspondências. O resultado sempre tem pelo menos um elemento (a string inteira quando nada corresponde).
import stdlib::regex::*;
fn main() -> i32 {
let sep: *Regex = Regex::compile(",|;").val;
let parts: *Vector<string> = sep.split("alpha,beta;gamma");
for let i: i32 = 0; i < parts.len(); i++ {
println!("part", i, parts.get(i)); // alpha / beta / gamma
}
// \s+ colapsa sequências de espaço em branco em separadores únicos.
let ws: *Regex = Regex::compile("\\s+").val;
let words: *Vector<string> = ws.split("the quick fox");
println!("nwords", words.len()); // 3
// Sem correspondência -> vetor de um único elemento (a string inteira).
let z: *Regex = Regex::compile("z").val;
let one: *Vector<string> = z.split("abc");
println!("one", one.len(), one.get(0)); // 1 abc
return 0;
}
API de conveniência com funções livres
Utilitários de uso único que compilam o padrão a cada chamada. Prefira manter um *Regex por perto em laços de alto desempenho.
| Função | Assinatura | Descrição |
|---|---|---|
regex_matches |
fn regex_matches(pat: string, s: string) -> bool |
Regex::compile(pat).val.matches(s); false em padrão inválido. |
regex_find |
fn regex_find(pat: string, s: string) -> ?*Match |
Regex::compile(pat).val.find(s); none() em padrão inválido. |
regex_replace_all |
fn regex_replace_all(pat: string, s: string, repl: string) -> string |
Regex::compile(pat).val.replace_all(s, repl); retorna s em padrão inválido. |
import stdlib::regex::*;
fn main() -> i32 {
if regex_matches("\\d+", "abc 42") { println!("matched"); }
match regex_find("(\\w+)@(\\w+)", "x@y") {
some(m) => println!(m.group(1), m.group(2)), // x y
none() => {},
}
println!(regex_replace_all("a1b2c3", "\\d", "#")); // a#b#c#
// Padrão inválido: silenciosamente retorna false / none() / a entrada.
if !regex_matches("(unclosed", "x") { println!("bad pattern swallowed"); }
return 0;
}
Sintaxe suportada
Literais e escapes
A maioria dos caracteres corresponde a si mesma. Escapes com barra invertida:
| Escape | Corresponde a |
|---|---|
\n \t \r \f \v |
nova linha, tabulação, retorno, avanço de página, tabulação vertical |
\a \e \0 |
sino (0x07), escape (0x1B), NUL (0x00) |
\xHH |
o byte com valor hexadecimal HH (ex.: \x41 = A) |
\. \\ \( ... |
um metacaractere literal |
Classes de caracteres
| Sintaxe | Corresponde a |
|---|---|
[abc] |
qualquer um de a, b, c |
[a-z] |
um intervalo de bytes |
[^a-z] |
negação (qualquer byte fora do conjunto) |
[a-zA-Z0-9_] |
união de intervalos |
[\d\s] |
classes predefinidas são permitidas dentro de [...] |
[]a] |
um ] colocado primeiro é um ] literal |
Classes predefinidas (utilizáveis de forma isolada ou dentro de [...]):
| Classe | Corresponde a | Negada |
|---|---|---|
\d |
dígitos 0-9 |
\D |
\w |
bytes de palavra [A-Za-z0-9_] |
\W |
\s |
espaço em branco \t\n\v\f\r e espaço |
\S |
. |
qualquer byte exceto \n (qualquer byte com a flag s) |
— |
import stdlib::regex::*;
fn main() -> i32 {
let hex: *Regex = Regex::compile("[0-9a-fA-F]+").val;
println!(hex.find("DEADbeef!").val.full()); // DEADbeef
let neg: *Regex = Regex::compile("[^aeiou ]+").val;
println!(neg.find("the fox").val.full()); // th
let byte: *Regex = Regex::compile("\\x41\\x42").val; // corresponde a "AB"
if byte.matches("xABy") { println!("hex byte ok"); }
let mix: *Regex = Regex::compile("[\\d.]+").val; // dígitos ou ponto
println!(mix.find("v3.14!").val.full()); // 3.14
return 0;
}
Quantificadores
| Quantificador | Repetições | Forma preguiçosa |
|---|---|---|
* |
0 ou mais | *? |
+ |
1 ou mais | +? |
? |
0 ou 1 | ?? |
{n} |
exatamente n |
{n}? |
{n,} |
n ou mais |
{n,}? |
{n,m} |
entre n e m |
{n,m}? |
Os quantificadores são gananciosos por padrão; adicionar ? os torna preguiçosos. A flag U (ou inline (?U)) inverte a ganância globalmente.
import stdlib::regex::*;
fn main() -> i32 {
let greedy: *Regex = Regex::compile("<.+>").val;
println!(greedy.find("<a><b>").val.full()); // <a><b>
let lazy: *Regex = Regex::compile("<.+?>").val;
println!(lazy.find("<a><b>").val.full()); // <a>
let bounded: *Regex = Regex::compile("a{2,3}").val;
println!(bounded.find("aaaa").val.full()); // aaa
let exact: *Regex = Regex::compile("\\d{3}").val;
println!(exact.find("12345").val.full()); // 123
// A flag U inverte a ganância padrão: <.+> se comporta como <.+?>.
let ung: *Regex = Regex::compile_with("<.+>", "U").val;
println!(ung.find("<a><b>").val.full()); // <a>
return 0;
}
Grupos, alternância e âncoras
| Sintaxe | Significado | ||
|---|---|---|---|
(...) |
grupo de captura | ||
(?:...) |
grupo sem captura | ||
(?<name>...) / (?P<name>...) |
grupo de captura nomeado | ||
| `a\ | b\ | c` | alternância |
^ $ |
início / fim de string (ou de linha com a flag m) |
||
\A \z \Z |
início / fim absoluto de string (\Z é tratado como \z) |
||
\b \B |
limite de palavra / não-limite de palavra |
import stdlib::regex::*;
fn main() -> i32 {
let alt: *Regex = Regex::compile("cat|dog|bird").val;
println!(alt.find("I have a dog").val.full()); // dog
let anch: *Regex = Regex::compile("^\\d+$").val;
if anch.matches("12345") { println!("all digits"); }
if !anch.matches("12a45") { println!("not all"); }
// \b: palavra inteira, não uma substring.
let word: *Regex = Regex::compile("\\bcat\\b").val;
if word.matches("a cat sat") { println!("whole word"); }
if !word.matches("category") { println!("no substring"); }
// flag m: ^ corresponde após cada nova linha.
let ml: *Regex = Regex::compile_with("^x", "m").val;
let hits: *Vector<*Match> = ml.find_all("ax\nx\nx");
println!("ml hits", hits.len()); // 2
return 0;
}
Retrorreferências
| Sintaxe | Significado |
|---|---|
\1 .. \9 |
corresponde ao mesmo texto capturado por um grupo numerado |
\k<name> |
corresponde ao mesmo texto capturado por um grupo nomeado |
Lookaround
| Sintaxe | Significado |
|---|---|
(?=...) |
lookahead positivo |
(?!...) |
lookahead negativo |
(?<=...) |
lookbehind positivo |
(?<!...) |
lookbehind negativo |
import stdlib::regex::*;
fn main() -> i32 {
// Lookahead positivo: foo apenas quando seguido de bar (bar não é consumido).
let la: *Regex = Regex::compile("foo(?=bar)").val;
println!(la.find("foobar").val.full()); // foo
// Lookahead negativo.
let nla: *Regex = Regex::compile("\\d+(?!px)").val;
if nla.matches("10em") { println!("nla ok"); }
// Lookbehind: dígitos precedidos por '$'.
let lb: *Regex = Regex::compile("(?<=\\$)\\d+").val;
println!(lb.find("price $42 yen").val.full()); // 42
// Retrorreferência: uma palavra duplicada.
let dup: *Regex = Regex::compile("\\b(\\w+)\\s+\\1\\b").val;
if dup.matches("the the cat") { println!("dup"); }
// Retrorreferência nomeada: correspondência entre tags de abertura e fechamento.
let tag: *Regex = Regex::compile("<(?<t>\\w+)>.*?</\\k<t>>").val;
if tag.matches("<b>hi</b>") { println!("tag ok"); }
return 0;
}
Flags
Passe como string de flags para compile_with, ou inline no padrão via (?flags) (define as flags a partir desse ponto) ou (?flags:subpadrão) (com escopo); (?flags-flags:...) desativa flags dentro do escopo.
| Flag | Constante | Efeito |
|---|---|---|
i |
RX_FLAG_I |
insensível a maiúsculas/minúsculas (somente ASCII) |
m |
RX_FLAG_M |
^/$ correspondem em quebras de linha |
s |
RX_FLAG_S |
. corresponde a \n (dot-all) |
x |
RX_FLAG_X |
estendido: espaço em branco sem escape e comentários # são ignorados |
U |
RX_FLAG_U |
não-ganancioso: inverte a ganância padrão |
import stdlib::regex::*;
fn main() -> i32 {
// (?i:...) — insensível a maiúsculas/minúsculas apenas dentro do grupo.
let scoped: *Regex = Regex::compile("(?i:hello) world").val;
if scoped.matches("HELLO world") { println!("scoped i"); }
if !scoped.matches("HELLO WORLD") { println!("outside still sensitive"); }
// (?x) — estendido: espaço em branco e comentários # são ignorados.
let ext: *Regex = Regex::compile("(?x) \\d+ # the number \n - \\d+").val;
if ext.matches("12-34") { println!("extended ok"); }
return 0;
}
import stdlib::regex::*;
fn main() -> i32 {
// Flags inline no nível superior + lookahead.
let re: *Regex = Regex::compile("(?i)foo(?=bar)").val;
if re.matches("FOObar") { println!("lookahead ok"); }
return 0;
}
Blocos de construção de baixo nível
Esses itens públicos sustentam o motor. A maioria dos programas nunca os acessa diretamente, mas são exportados e documentados aqui por completude.
CharClass
Um conjunto de intervalos de bytes inclusivos, opcionalmente negado. Usado internamente para classes; você pode construir um manualmente.
pub struct CharClass {
ranges: *Vector<i32>, // [lo1, hi1, lo2, hi2, ...] inclusivo
negated: bool,
}
| Método | Assinatura | Descrição |
|---|---|---|
new |
fn new() -> *CharClass |
Classe vazia, não negada. |
add |
fn add(self: *CharClass, lo: i32, hi: i32) |
Adiciona um intervalo de bytes inclusivo. |
contains |
fn contains(self: *CharClass, b: i32) -> bool |
Testa o byte b (respeita negated). |
import stdlib::regex::*;
fn main() -> i32 {
let cc: *CharClass = CharClass::new();
cc.add(48, 57); // '0'..'9'
cc.add(65, 70); // 'A'..'F'
if cc.contains(53) { println!("'5' in class"); } // true
if !cc.contains(103) { println!("'g' not in class"); } // true
return 0;
}
Constantes exportadas
Estas nomeiam os opcodes internos, tipos de nó AST, bits de flag, tipos de asserção e limites. São de interesse principalmente ao inspecionar re.flags ou ao estender o motor.
| Grupo | Constantes |
|---|---|
| Bits de flag | RX_FLAG_I (1), RX_FLAG_M (2), RX_FLAG_S (4), RX_FLAG_X (8), RX_FLAG_U (16) |
| Tipos de asserção | RX_AHEAD_POS (0), RX_AHEAD_NEG (1), RX_BEHIND_POS (2), RX_BEHIND_NEG (3) |
| Limites | RX_MAX_GROUPS (64) |
| Opcodes da VM | RX_OP_CHAR, RX_OP_ANY, RX_OP_ANY_NL, RX_OP_CLASS, RX_OP_BOL, RX_OP_EOL, RX_OP_STR_BEG, RX_OP_STR_END, RX_OP_WORDB, RX_OP_NWORDB, RX_OP_JMP, RX_OP_SPLIT, RX_OP_SAVE, RX_OP_BACKREF, RX_OP_ASSERT, RX_OP_ASRT_END, RX_OP_MATCH |
| Tipos de nó AST | RX_AST_LIT, RX_AST_ANY, RX_AST_CLASS, RX_AST_CONCAT, RX_AST_ALT, RX_AST_QUANT, RX_AST_GROUP, RX_AST_ANCHOR, RX_AST_BACK, RX_AST_LOOK |
Os bits de flag são combináveis com OR, então você pode testar re.flags:
import stdlib::regex::*;
fn main() -> i32 {
let re: *Regex = Regex::compile_with("abc", "is").val;
if (re.flags & RX_FLAG_I) != 0 { println!("case-insensitive"); }
if (re.flags & RX_FLAG_S) != 0 { println!("dot-all"); }
return 0;
}
Tipos internos
RxNode (nó AST), RxParser (parser de padrões) e RxCompiler (compilador de AST para bytecode) são structs exportadas usadas internamente por compile. Elas não possuem uma superfície de métodos públicos estável e devem ser tratadas como detalhe de implementação — não dependa de seus campos.
Não suportado / limitações conhecidas
Documentado honestamente para que você não busque recursos que se comportam de forma silenciosamente diferente:
| Recurso | Status |
|---|---|
Classes de propriedade Unicode (\p{...}), \w/./dobramento de maiúsculas compatível com Unicode |
Não suportado — o motor é orientado a bytes; i dobra apenas ASCII. |
Classes bracket POSIX ([[:alpha:]]) |
Não suportado — use intervalos explícitos ou \d/\w/\s. |
Grupos atômicos (?>...), quantificadores possessivos (a++, a*+) |
Não suportado. |
Condicionais (?(1)...), recursão (?R), chamadas de subrotina (?1) |
Não suportado. |
Comentários via (?#...) |
Não suportado (use a flag x com #). |
Semântica de \Z (antes de uma nova linha final) |
Tratado de forma idêntica a \z (fim absoluto). |
Escapes octais além de \0, escapes de controle \cX, \Q...\E |
Não suportado. |
Token de substituição ${name} como literal de string Glide puro |
Conflita com a interpolação de string Glide — veja o callout em Substituindo. |
Veja também
- strings —
split,contains,substring,to_lowerpara manipulação de texto sem regex (mais barato quando você não precisa de um padrão). - vectors — o
*Vector<*Match>/*Vector<string>retornado porfind_all/split. - collections — o
HashMapque sustenta a tabela nome→índice dos grupos nomeados. - prelude — as convenções de
?*Match/!*Regex(some/none/ok/err) usadas em todo o texto.