|
| 1 | +# Classes de caracteres |
| 2 | + |
| 3 | +Considere uma tarefa prática - temos um número de telefone como `"+7(903)-123-45-67"` e precisamos transformá-lo em números puros: `79031234567`. |
| 4 | + |
| 5 | +Para fazer isso, podemos encontrar e remover qualquer coisa que não seja um número. Classes de personagens podem ajudar com isso. |
| 6 | + |
| 7 | +Uma *classe de caracteres* é uma notação especial que corresponde a qualquer símbolo de um determinado conjunto. |
| 8 | + |
| 9 | +Para começar, vamos explorar a classe "digit". Está escrito como `padrão: \d` e corresponde a "qualquer dígito único". |
| 10 | + |
| 11 | +Por exemplo, vamos encontrar o primeiro dígito no número de telefone: |
| 12 | + |
| 13 | +```js run |
| 14 | +let str = "+7(903)-123-45-67"; |
| 15 | + |
| 16 | +let regexp = /\d/; |
| 17 | + |
| 18 | +alert( str.match(regexp) ); // 7 |
| 19 | +``` |
| 20 | + |
| 21 | +Sem a flag `padrão:g`, a expressão regular procura apenas a primeira correspondência, que é o primeiro dígito `padrão:\d`. |
| 22 | + |
| 23 | +Vamos adicionar a flag `padrão:g` para encontrar todos os dígitos: |
| 24 | + |
| 25 | +```js run |
| 26 | +let str = "+7(903)-123-45-67"; |
| 27 | + |
| 28 | +let regexp = /\d/g; |
| 29 | + |
| 30 | +alert( str.match(regexp) ); // matriz de correspondências: 7,9,0,3,1,2,3,4,5,6,7 |
| 31 | + |
| 32 | +// vamos criar o número de telefone apenas com dígitos: |
| 33 | +alert( str.match(regexp).join('') ); // 79031234567 |
| 34 | +``` |
| 35 | + |
| 36 | +Essa era uma classe de caracteres para dígitos. Existem outras classes de caracteres também. |
| 37 | + |
| 38 | +As mais usadas são: |
| 39 | + |
| 40 | +`padrão:\d` ("d" é de "digit") |
| 41 | +: Um dígito: um caractere de `0` a `9`. |
| 42 | + |
| 43 | +`padrão:\s` ("s" é de "space") |
| 44 | +: Um símbolo de espaço: inclui espaços, tabulações `\t`, novas linhas `\n` e alguns outros caracteres raros, como `\v`, `\f` and `\r`. |
| 45 | + |
| 46 | +`padrão:\w` ("w" é de "word") |
| 47 | +: Um caractere de texto: uma letra do alfabeto latino ou um dígito ou um sublinhado `_`. Letras não latinas (como cirílico ou hindu) não pertecem ao `padrão:\w`. |
| 48 | + |
| 49 | +Por exemplo, `padrão:\d\s\w` significa um "dígito" seguido de um "caractere de espaço" seguido de um "caractere de texto", como `correspondência:1 a`. |
| 50 | + |
| 51 | +**Uma regexp pode conter símbolos regulares e classes de caracteres.** |
| 52 | + |
| 53 | +Por exemplo, `padrão:CSS\d` corresponde a uma string `correspondência:CSS` com um dígito após: |
| 54 | + |
| 55 | +```js run |
| 56 | +let str = "Existe CSS4?"; |
| 57 | +let regexp = /CSS\d/ |
| 58 | + |
| 59 | +alert( str.match(regexp) ); // CSS4 |
| 60 | +``` |
| 61 | + |
| 62 | +Também podemos usar muitas classes de caracteres: |
| 63 | + |
| 64 | +```js run |
| 65 | +alert( "Eu amo HTML5!".match(/\s\w\w\w\w\d/) ); // ' HTML5' |
| 66 | +``` |
| 67 | + |
| 68 | +A correspondência (cada classe de caracteres regexp possui o caractere de resultado correspondente): |
| 69 | + |
| 70 | + |
| 71 | + |
| 72 | +## Classes inversas |
| 73 | + |
| 74 | +Para cada classe de caractere existe uma "classe inversa", denotada com a mesma letra, mas em maiúsculas. |
| 75 | + |
| 76 | +O "inverso" significa que ele corresponde a todos os outros caracteres, por exemplo: |
| 77 | + |
| 78 | +`padrão:\D` |
| 79 | +: Sem dígito: qualquer caractere, exceto `padrão:\d`, por exemplo, uma letra. |
| 80 | + |
| 81 | +`padrão:\S` |
| 82 | +: Sem espaço: qualquer caractere, exceto `padrão:\s`, por exemplo, uma letra. |
| 83 | + |
| 84 | +`padrão:\W` |
| 85 | +: Caractere não verbal: qualquer coisa, exceto `padrão:\w`, por exemploo uma letra não latina ou um espaço. |
| 86 | + |
| 87 | +No início do capítulo, vimos como criar um número de telefone somente para números a partir de uma string como `subject:+7(903)-123-45-67`: encontre todos os dígitos e junte-se a eles. |
| 88 | + |
| 89 | +```js run |
| 90 | +let str = "+7(903)-123-45-67"; |
| 91 | + |
| 92 | +alert( str.match(/\d/g).join('') ); // 79031234567 |
| 93 | +``` |
| 94 | + |
| 95 | +Uma maneira alternativa e mais curta é encontrar um `padrão:\D` não-dígito e removê-lo da string: |
| 96 | + |
| 97 | +```js run |
| 98 | +let str = "+7(903)-123-45-67"; |
| 99 | + |
| 100 | +alert( str.replace(/\D/g, "") ); // 79031234567 |
| 101 | +``` |
| 102 | + |
| 103 | +## Um ponto é "qualquer caractere" |
| 104 | + |
| 105 | +Um ponto `padrão:.` é uma classe de caractere especial que corresponde a "qualquer caractere, exceto uma nova linha". |
| 106 | + |
| 107 | +Por exemplo: |
| 108 | + |
| 109 | +```js run |
| 110 | +alert( "Z".match(/./) ); // Z |
| 111 | +``` |
| 112 | + |
| 113 | +Ou no meio de uma regexp: |
| 114 | + |
| 115 | +```js run |
| 116 | +let regexp = /CS.4/; |
| 117 | + |
| 118 | +alert( "CSS4".match(regexp) ); // CSS4 |
| 119 | +alert( "CS-4".match(regexp) ); // CS-4 |
| 120 | +alert( "CS 4".match(regexp) ); // CS 4 (o espaço é também um caractere) |
| 121 | +``` |
| 122 | + |
| 123 | +Observe que um ponto significa "qualquer caractere", mas não a "ausência de um caractere". Deve haver um caractere para corresponder a ele: |
| 124 | + |
| 125 | +```js run |
| 126 | +alert( "CS4".match(/CS.4/) ); // null, sem correspondência porque não há caractere para o ponto |
| 127 | +``` |
| 128 | + |
| 129 | +### Ponto como literalmente qualquer caractere com a flag "s" |
| 130 | + |
| 131 | +Por padrão, um ponto não corresponde ao caractere de nova linha `\n`. |
| 132 | + |
| 133 | +Por exemplo, a regexp `padrão:A.B` corresponde `corresponde:A` e, em seguida, `corresponde:B` com qualquer caractere entre eles, exceto uma nova linha `\n`: |
| 134 | + |
| 135 | +```js run |
| 136 | +alert( "A\nB".match(/A.B/) ); // null (sem correspondência) |
| 137 | +``` |
| 138 | + |
| 139 | +Há muitas situações em que gostaríamos que um ponto significasse literalmente "qualquer caractere", incluindo a nova linha. |
| 140 | + |
| 141 | +É o que flag `padrão:s` faz. Se uma regexp possui, então um ponto `padrão:.` corresponde literalmente a qualquer caractere: |
| 142 | + |
| 143 | +```js run |
| 144 | +alert( "A\nB".match(/A.B/s) ); // A\nB (correspondência!) |
| 145 | +``` |
| 146 | + |
| 147 | +````warn header="Não suportado no Firefox, IE, Edge" |
| 148 | +Verifique <https://caniuse.com/#search=dotall> para obter o estado de suporte mais recente. No momento da redação deste documento, não inclui o Firefox, IE, Edge. |
| 149 | +
|
| 150 | +Felizmente, há uma alternativa, que funciona em qualquer lugar. Podemos usar uma regexp como `padrão:[\s\S]` para corresponder a "qualquer caractere". |
| 151 | +
|
| 152 | +```js run |
| 153 | +alert( "A\nB".match(/A[\s\S]B/) ); // A\nB (match!) |
| 154 | +``` |
| 155 | +
|
| 156 | +O padrão `padrão:[\s\S]` diz literalmente: "um caractere de espaço OU não um caractere de espaço". Em outras palavras, "qualquer coisa". Poderíamos usar outro par de classes complementares, como `padrão:[\d\D]`, que não importa. Ou mesmo o padrão `padrão:[^]` - pois significa corresponder a qualquer caractere, exceto nada. |
| 157 | +
|
| 158 | +Também podemos usar esse truque se quisermos os dois tipos de "pontos" no mesmo padrão: o ponto real `padrão:.` comportando-se da maneira regular ("não incluindo uma nova linha") e também uma maneira de combinar "qualquer caractere" com `padrão:[\s\S]` ou similar. |
| 159 | +```` |
| 160 | + |
| 161 | +````warn header="Preste atenção nos espaços" |
| 162 | +Geralmente prestamos pouca atenção aos espaços. Para nós, as strings `sujeito:1-5` e `sujeito:1 - 5` são quase idênticas. |
| 163 | +
|
| 164 | +Mas se uma regexp não leva em consideração os espaços, ela pode falhar. |
| 165 | +
|
| 166 | +Vamos tentar encontrar dígitos separados por um hífen: |
| 167 | +
|
| 168 | +```js run |
| 169 | +alert( "1 - 5".match(/\d-\d/) ); // null, sem correspondência! |
| 170 | +``` |
| 171 | +
|
| 172 | +Vamos corrigi-lo adicionando espaços ao padrão regexp `padrão:\d - \d`: |
| 173 | +
|
| 174 | +```js run |
| 175 | +alert( "1 - 5".match(/\d - \d/) ); // 1 - 5, agora funciona |
| 176 | +// ou podemos usar a classe \s: |
| 177 | +alert( "1 - 5".match(/\d\s-\s\d/) ); // 1 - 5, também funciona |
| 178 | +``` |
| 179 | +
|
| 180 | +**Um espaço é um caractere. Igual em importância com qualquer outro caractere.** |
| 181 | +
|
| 182 | +Não podemos adicionar ou remover espaços de uma expressão regular e esperamos funcionar da mesma maneira. |
| 183 | +
|
| 184 | +Em outras palavras, em uma expressão regular, todos os caracteres são importantes, espaços também. |
| 185 | +```` |
| 186 | + |
| 187 | +## Resumo |
| 188 | + |
| 189 | +Existem as seguintes classes de caracteres: |
| 190 | + |
| 191 | +- `padrão:\d` - dígitos. |
| 192 | +- `padrão:\D` - sem dígitos. |
| 193 | +- `padrão:\s` - símbolos de espaço, tabulações, novas linhas. |
| 194 | +- `padrão:\S` - todos, exceto `padrão:\s`. |
| 195 | +- `padrão:\w` - Letras latinas, dígitos, sublinhado `'_'`. |
| 196 | +- `padrão:\W` - todos, exceto `padrão:\w`. |
| 197 | +- `padrão:.` - qualquer caractere se estiver com a flag regexp `'s' `; caso contrário, qualquer um, exceto uma nova linha `\n`. |
| 198 | + |
| 199 | +...Mas isso não é tudo! |
| 200 | + |
| 201 | +A codificação unicode, usada pelo JavaScript para strings, fornece muitas propriedades para caracteres, como: a qual idioma a letra pertence (se é uma letra), é um sinal de pontuação etc. |
| 202 | + |
| 203 | +Também podemos pesquisar por essas propriedades. Isso requer a flag `padrão:u`, abordada no próximo artigo. |
0 commit comments