Comentando expressões regulares

11

Existem práticas comuns para comentar as expressões regulares: comentários embutidos que referem parte diferente do RegEx ou comentário geral para todas as expressões?

m0nhawk
fonte
2
Existem, mas você precisa ser mais específico. Por exemplo, o Bash suporta comentários embutidos e o Python oferece expressões regulares detalhadas.
Sakisk
6
Minha regra geral para expressões regulares é: se você precisar comentar a expressão regular, é muito complicado.
zzzzBov
1
E sempre incluir este link: regexcrossword.com
Kieveli
Não concordo necessariamente que, se você tiver que comentar, é muito complicado. Um regex complicado ainda pode economizar toneladas de código imprescindível. Use um bom nome de variável descritiva para atribuir a regex. Se ainda não estiver claro o suficiente, use um breve comentário para transmitir a intenção original por trás da expressão regular.
22414 Craig

Respostas:

10

A meu ver, uma boa prática é declarar concisamente nos comentários qual é a idéia geral da expressão regular. Isso poupa a outros desenvolvedores (ou às vezes a você mesmo) o trabalho de copiar e colar a regex em um analisador como o RegExr , apenas para entender o que ele faz.

pleinolijf
fonte
2
O RegExr acontecerá de qualquer maneira, a menos que o dev seja um savant de regex. Mas concordo em fornecer uma descrição geral; é isso que faço com minhas expressões regulares.
Robert Harvey
3
+1: Qualquer coisa mais detalhada acabará sendo um curso intensivo em regex como um comentário.
Matt
Esta resposta e os comentários @zzzzBov fazem sentido.
M0nhawk 08/12/12
1
Ele não apenas evita o aborrecimento do exame tedioso da expressão regular para entendê-la, mas também torna clara a intenção do programador original, especialmente dada a possibilidade distinta de que o programador original tenha entendido a expressão regular incorretamente desde o início. Dito isto, em muitos casos, atribuir a regex a um bom nome de variável pode contar muito para fornecer documentação adequada de intenção.
22414 Craig
9

Essa é uma resposta específica do idioma, mas nenhum idioma é declarado na pergunta.

O livro "Dive Into Python" sugere a implementação de comentários usando expressões regulares verbais :

O Python permite fazer isso com algo chamado expressões regulares detalhadas. Uma expressão regular detalhada é diferente de uma expressão regular compacta de duas maneiras:

  • Espaço em branco é ignorado. Espaços, tabulações e retornos de carro não são correspondidos como espaços, tabulações e retornos de carro. Eles não são iguais. (Se você deseja combinar um espaço em uma expressão regular detalhada, precisará escapar dele colocando uma barra invertida na frente dele.)
  • Comentários são ignorados. Um comentário em uma expressão regular detalhada é como um comentário no código Python: começa com um #caractere e vai até o final da linha. Nesse caso, é um comentário dentro de uma string de várias linhas, em vez de dentro do código-fonte, mas funciona da mesma maneira.

Exemplo:

>>> pattern = """
^                   # beginning of string
M{0,4}              # thousands - 0 to 4 M's
(CM|CD|D?C{0,3})    # hundreds - 900 (CM), 400 (CD), 0-300 (0 to 3 C's),
                    #            or 500-800 (D, followed by 0 to 3 C's)
(XC|XL|L?X{0,3})    # tens - 90 (XC), 40 (XL), 0-30 (0 to 3 X's),
                    #        or 50-80 (L, followed by 0 to 3 X's)
(IX|IV|V?I{0,3})    # ones - 9 (IX), 4 (IV), 0-3 (0 to 3 I's),
                    #        or 5-8 (V, followed by 0 to 3 I's)
$                   # end of string
"""
>>> re.search(pattern, 'M', re.VERBOSE)                1

Fonte e mais detalhes aqui

Esse método tem uma pequena desvantagem de que o responsável pela chamada deve saber que o padrão está escrito em um formato detalhado e chamá-lo de acordo.

Rotem
fonte
2
Em vez de armazenar o padrão em uma variável, você pode usá-lo re.compileno ponto em que define seu padrão e armazenar apenas o objeto resultante. Dessa forma, os sinalizadores de compilação do padrão (inclusive re.VERBOSE) não precisam ser separados do próprio padrão.
John Bartholomew
Resposta realmente útil, obrigado! Mas como posso corresponder a #se estou usando a bandeira detalhada? A propósito: os links de origem parecem estar inoperantes.
Winklerrr 22/05/19
Ok, então #pode ser correspondido literalmente, quando dentro de uma classe de caracteres: [#](fonte: docs.python.org/3/library/re.html#re.X )
winklerrr
8

Normalmente, escreverei uma regex e não explicarei as partes individuais da regex, mas qual é seu objetivo. É isso que e por quê. É um pouco como perguntar "Como devem ser meus comentários?" ao qual alguém diria " Não escreva o que o código está fazendo, escreva por que o código está fazendo o que faz "

// Strip the leading "?" and remove the query parameters "offset=<integer>" & "count=<integer> so we have a pattern of the request"          
var search = location.search.substring(1).replace(/offset=[0-9]+?&/g, "").replace(/count=[0-9]+?&/g, "");

A menos que você esteja tentando ensinar alguém sobre regexes por meio de comentários no código, não acho que seja possível explicar o que cada peça individual fará. Ao trabalhar com outros programadores, você pode assumir com segurança que alguém saberia algo como expressões regulares globais.


fonte
3
você ficaria surpreso ...
Matt
6

Eu acho que depende realmente de como você está montando o regex. De um modo geral, acho que seria uma má idéia colocar comentários dentro da própria cadeia de caracteres de regex (não é possível na maioria dos cenários, pelo que sei). Se você realmente precisar comentar partes específicas de uma expressão regular (você está tentando ensinar alguém?), Divida cada pedaço em seqüências de caracteres separadas em suas próprias linhas e comente cada linha usando o processo normal de comentários para sua linguagem de programação. Caso contrário, a resposta de pleinolijf é muito boa.

exemplo:

string myregex = "\s" // Match any whitespace once
+ "\n"  // Match one newline character
+ "[a-zA-Z]";  // Match any letter
Matt
fonte
4

Normalmente, defino uma constante de sequência cujo nome descreve o objetivo geral da expressão regular.

Por exemplo:

const string FloatingPointNumberPattern = @"[-+]?[0-9]*\.?[0-9]+";

Você pode adicionar um comentário acima dessa constante para fornecer uma descrição, mas geralmente o nome da constante em si deve ser suficiente.

Bernard
fonte
1
Uma coisa extra que eu gosto nessa resposta é que, se ela for usada em mais de um ponto, a intenção também terá que ser contornada - sem esquecer de comentar.
J Trana
3

Em alguns cenários, os desenvolvedores podem estar usando expressões regulares para corresponder ao texto fora de seu domínio típico. Os desenvolvedores originais podem ter passado por muitas iterações, capturando vários casos extremos que podem ter sido descobertos apenas por esse processo iterativo. Portanto, os desenvolvedores subseqüentes podem não estar cientes de muitos dos casos extremos com os quais os desenvolvedores originais lidaram, mesmo que estejam cientes do caso geral.

Em casos como esses, pode valer a pena documentar exemplos das variações. A localização desta documentação pode variar dependendo da quantidade (por exemplo, não necessariamente no código).

Uma maneira de abordar isso é assumir que futuros desenvolvedores terão apenas conhecimento básico, como o funcionamento das expressões regulares, mas nenhum conhecimento que você (1) tenha antes do desenvolvimento das expressões regulares que não seriam necessariamente conhecidas pelo usuário. desenvolvedores futuros ou (2) conhecimento que você adquiriu durante o desenvolvimento (por exemplo, casos extremos que foram descobertos).

Por exemplo, se durante o desenvolvimento você disser algo como "Ah, eu não sabia que X poderia assumir esse formato", vale a pena documentar isso (e talvez a parte do regex que lida com essa variação).

bstovall
fonte
2

Os comentários devem adicionar informações úteis que não são óbvias no código.

  1. Facilite a compreensão do que a expressão deve fazer no nível de requisitos, no próprio código ou em um comentário. Qual é a intenção por trás da expressão é validar endereços de e-mail ou escolher números de telefone canadenses.
  2. Facilite a compreensão do que a expressão está realmente fazendo, ou seja, o que a expressão avalia. Primeiro, tente esclarecer dividindo a expressão. Se você primeiro verificar todos os hífens, remover todos os números e criar uma expressão de duas partes com variáveis ​​que mantêm os valores intermediários, facilitará a leitura e o leitor ficará mais fácil. capaz de percorrer sua lógica, um passo de cada vez. (Existe uma resposta famosa para uma pergunta no SE em que alguém está tentando decifrar algum código antigo que envolve manipulação de bits '>>' e descobrindo se certos sinalizadores estão definidos, onde a resposta estabelece não apenas o que o código realmente faz, mas como o autor da pergunta deve desconstruir esse tipo de código no futuro, que é exatamente o que estou tentando descrever, mas posso '

Existem poucos aplicativos que precisam de todos os ciclos finais, se você estiver combinando conjuntos de dados maciços de padrões, talvez haja uma maneira melhor, talvez não, mas, na maioria das vezes, o tempo de execução extra não é tão importante.

E lembre-se de que a próxima pessoa a encontrar seu código e corrigir um bug pode ser você em seis meses e não há como você se lembrar do que deveria fazer.

Encaitar
fonte
1

Extraia o RegEx em uma classe separada em um com um nome significativo. Depois, documentava o código com testes automatizados.

Isso garantirá

  • Que o código realmente funciona - também para casos de canto
  • Garante que uma rápida "correção de bug" não estrague muitos casos de canto
  • Pode documentar otimizações onde o retorno está desativado

Naturalmente, sua classe pode hospedar várias regexs.

Carlo V. Dango
fonte