Sub-expressões são delimitadas por parênteses e podem ser aninhadas. Marcar parte de uma expressão como uma sub-expressão tem dois objetivos:
Localizar um conjunto de alternativas. Por exemplo, a expressão
cat(aract|erpillar|)
corresponde a uma das três palavras: "cat",
"cataract" ou "caterpillar". Sem os parênteses, corresponderia a
"cataract", "erpillar" ou a uma string vazia.
Definir a sub-expressão como um grupo de captura (como definido acima). Quando toda a expressão tem correspondência, a parte da string de entrada que correspondeu à sub-expressão é passada de volta à função chamadora através do argumento ovector da função pcre_exec(). Parênteses de abertura são contados da esquerda para a direita (iniciando de 1) para obter os números dos grupos de captura.
Por exemplo, se a string "the red king" é correspondida pela
expressão
the ((red|white) (king|queen))
os grupos de captura são "red king", "red" e "king",
e são numerados com 1, 2 e 3.
O fato dos parênteses terem duas funções nem
sempre ajuda. Frequentemente é necessária uma sub-expressão de
agrupamento sem a necessidade de captura. Se um parêntese
de abertura for seguido por "?:", a sub-expressão não
faz nenhuma captura, e não é contado ao computar o
número de sub-expressões de captura subsequentes. Por exemplo,
se a string "the white queen" é correspondida pela
expressão
the ((?:red|white) (king|queen))
as substrings capturadas são "white queen" e "queen", e
são numeradas com 1 e 2. O número máximo de subtrings capturadas
é 65535. Porém, pode não ser possível compilar expressões deste tamanho,
dependendo das opções de configuração da biblioteca libpcre.
Como um atalho conveniente, se qualquer configuração de opção for necessária no início de uma sub-expressão sem captura, as letras de opções podem aparecer entre o "?" e o ":". Assim, as duas expressões
(?i:saturday|sunday) (?:(?i)saturday|sunday)
correspondem exatamente ao mesmo conjunto de strings. Como os ramos alternativos são testados da esquerda para a direita, e as opções não são redefinidas até que se alcance o final da sub-expressão, uma configuração de opção em um ramo não afeta ramos subsequentes, portanto as expressões acima correspondem a "SUNDAY" e também a "Saturday".
É possível nomear uma sub-expressão usando a sintaxe
(?P<nome>expressão)
. Esta sub-expressão será então
indexada no array de correspondências pela sua posição numérica normal e
também pelo nome. Há duas sintaxes alternativas:
(?<nome>expressão)
e (?'nome'expressão)
.
Algumas vezes é necessário ter correspondências múltiplas, mas não ter
sub-grupos alternados em uma expressão regular. Normalmente, cada um destes receberia
seu próprio número de referência embora apenas um seria
possivelmente correspondido. Para contornar isto, a sintaxe (?|
permite
ter números duplicados. Considere o caso abaixo, onde a expressão regular corresponde à
string Sunday
:
(?:(Sat)ur|(Sun))day
Aqui, Sun
é armazenado na referência 2, enquanto que
a referência 1 está vazia. Corresponder Saturday
gera
a referência 1 para Sat
enquanto que a referência 2
não existirá. Modificar a expressão usando (?|
corrige
este problema:
(?|(Sat)ur|(Sun))day
Usando esta expressão, tanto Sun
quanto Sat
seriam armazenadas na referência 1.