|
1 | | -# Character classes |
| 1 | +# Classes de caracteres |
2 | 2 |
|
3 | | -Consider a practical task -- we have a phone number `"+7(903)-123-45-67"`, and we need to turn it into pure numbers: `79035419441`. |
| 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 | 4 |
|
5 | | -To do so, we can find and remove anything that's not a number. Character classes can help with that. |
| 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 | 6 |
|
7 | | -A character class is a special notation that matches any symbol from a certain set. |
| 7 | +Uma *classe de caracteres* é uma notação especial que corresponde a qualquer símbolo de um determinado conjunto. |
8 | 8 |
|
9 | | -For the start, let's explore a "digit" class. It's written as `\d`. We put it in the pattern, that means "any single digit". |
| 9 | +Para começar, vamos explorar a classe "digit". Está escrito como `padrão: \d` e corresponde a "qualquer dígito único". |
10 | 10 |
|
11 | | -For instance, the let's find the first digit in the phone number: |
| 11 | +Por exemplo, vamos encontrar o primeiro dígito no número de telefone: |
12 | 12 |
|
13 | 13 | ```js run |
14 | 14 | let str = "+7(903)-123-45-67"; |
15 | 15 |
|
16 | | -let reg = /\d/; |
| 16 | +let regexp = /\d/; |
17 | 17 |
|
18 | | -alert( str.match(reg) ); // 7 |
| 18 | +alert( str.match(regexp) ); // 7 |
19 | 19 | ``` |
20 | 20 |
|
21 | | -Without the flag `g`, the regular expression only looks for the first match, that is the first digit `\d`. |
| 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 | 22 |
|
23 | | -Let's add the `g` flag to find all digits: |
| 23 | +Vamos adicionar a flag `padrão:g` para encontrar todos os dígitos: |
24 | 24 |
|
25 | 25 | ```js run |
26 | 26 | let str = "+7(903)-123-45-67"; |
27 | 27 |
|
28 | | -let reg = /\d/g; |
| 28 | +let regexp = /\d/g; |
29 | 29 |
|
30 | | -alert( str.match(reg) ); // array of matches: 7,9,0,3,1,2,3,4,5,6,7 |
| 30 | +alert( str.match(regexp) ); // matriz de correspondências: 7,9,0,3,1,2,3,4,5,6,7 |
31 | 31 |
|
32 | | -alert( str.match(reg).join('') ); // 79035419441 |
| 32 | +// vamos criar o número de telefone apenas com dígitos: |
| 33 | +alert( str.match(regexp).join('') ); // 79031234567 |
33 | 34 | ``` |
34 | 35 |
|
35 | | -That was a character class for digits. There are other character classes as well. |
| 36 | +Essa era uma classe de caracteres para dígitos. Existem outras classes de caracteres também. |
36 | 37 |
|
37 | | -Most used are: |
| 38 | +As mais usadas são: |
38 | 39 |
|
39 | | -`\d` ("d" is from "digit") |
40 | | -: A digit: a character from `0` to `9`. |
| 40 | +`padrão:\d` ("d" é de "digit") |
| 41 | +: Um dígito: um caractere de `0` a `9`. |
41 | 42 |
|
42 | | -`\s` ("s" is from "space") |
43 | | -: A space symbol: that includes spaces, tabs, newlines. |
| 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`. |
44 | 45 |
|
45 | | -`\w` ("w" is from "word") |
46 | | -: A "wordly" character: either a letter of English alphabet or a digit or an underscore. Non-english letters (like cyrillic or hindi) do not belong to `\w`. |
| 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`. |
47 | 48 |
|
48 | | -For instance, `pattern:\d\s\w` means a "digit" followed by a "space character" followed by a "wordly character", like `"1 a"`. |
| 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`. |
49 | 50 |
|
50 | | -**A regexp may contain both regular symbols and character classes.** |
| 51 | +**Uma regexp pode conter símbolos regulares e classes de caracteres.** |
51 | 52 |
|
52 | | -For instance, `pattern:CSS\d` matches a string `match:CSS` with a digit after it: |
| 53 | +Por exemplo, `padrão:CSS\d` corresponde a uma string `correspondência:CSS` com um dígito após: |
53 | 54 |
|
54 | 55 | ```js run |
55 | | -let str = "CSS4 is cool"; |
56 | | -let reg = /CSS\d/ |
| 56 | +let str = "Existe CSS4?"; |
| 57 | +let regexp = /CSS\d/ |
57 | 58 |
|
58 | | -alert( str.match(reg) ); // CSS4 |
| 59 | +alert( str.match(regexp) ); // CSS4 |
59 | 60 | ``` |
60 | 61 |
|
61 | | -Also we can use many character classes: |
| 62 | +Também podemos usar muitas classes de caracteres: |
62 | 63 |
|
63 | 64 | ```js run |
64 | | -alert( "I love HTML5!".match(/\s\w\w\w\w\d/) ); // 'HTML5' |
| 65 | +alert( "Eu amo HTML5!".match(/\s\w\w\w\w\d/) ); // ' HTML5' |
65 | 66 | ``` |
66 | 67 |
|
67 | | -The match (each character class corresponds to one result character): |
| 68 | +A correspondência (cada classe de caracteres regexp possui o caractere de resultado correspondente): |
68 | 69 |
|
69 | 70 |  |
70 | 71 |
|
71 | | -## Word boundary: \b |
| 72 | +## Classes inversas |
72 | 73 |
|
73 | | -A word boundary `pattern:\b` -- is a special character class. |
| 74 | +Para cada classe de caractere existe uma "classe inversa", denotada com a mesma letra, mas em maiúsculas. |
74 | 75 |
|
75 | | -It does not denote a character, but rather a boundary between characters. |
| 76 | +O "inverso" significa que ele corresponde a todos os outros caracteres, por exemplo: |
76 | 77 |
|
77 | | -For instance, `pattern:\bJava\b` matches `match:Java` in the string `subject:Hello, Java!`, but not in the script `subject:Hello, JavaScript!`. |
| 78 | +`padrão:\D` |
| 79 | +: Sem dígito: qualquer caractere, exceto `padrão:\d`, por exemplo, uma letra. |
78 | 80 |
|
79 | | -```js run |
80 | | -alert( "Hello, Java!".match(/\bJava\b/) ); // Java |
81 | | -alert( "Hello, JavaScript!".match(/\bJava\b/) ); // null |
82 | | -``` |
83 | | - |
84 | | -The boundary has "zero width" in a sense that usually a character class means a character in the result (like a wordly character or a digit), but not in this case. |
85 | | - |
86 | | -The boundary is a test. |
87 | | - |
88 | | -When regular expression engine is doing the search, it's moving along the string in an attempt to find the match. At each string position it tries to find the pattern. |
89 | | - |
90 | | -When the pattern contains `pattern:\b`, it tests that the position in string is a word boundary, that is one of three variants: |
91 | | - |
92 | | -- Immediately before is `\w`, and immediately after -- not `\w`, or vise versa. |
93 | | -- At string start, and the first string character is `\w`. |
94 | | -- At string end, and the last string character is `\w`. |
95 | | - |
96 | | -For instance, in the string `subject:Hello, Java!` the following positions match `\b`: |
97 | | - |
98 | | - |
99 | | - |
100 | | -So it matches `pattern:\bHello\b`, because: |
101 | | - |
102 | | -1. At the beginning of the string the first `\b` test matches. |
103 | | -2. Then the word `Hello` matches. |
104 | | -3. Then `\b` matches, as we're between `o` and a space. |
105 | | - |
106 | | -Pattern `pattern:\bJava\b` also matches. But not `pattern:\bHell\b` (because there's no word boundary after `l`) and not `Java!\b` (because the exclamation sign is not a wordly character, so there's no word boundary after it). |
| 81 | +`padrão:\S` |
| 82 | +: Sem espaço: qualquer caractere, exceto `padrão:\s`, por exemplo, uma letra. |
107 | 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. |
108 | 86 |
|
109 | | -```js run |
110 | | -alert( "Hello, Java!".match(/\bHello\b/) ); // Hello |
111 | | -alert( "Hello, Java!".match(/\bJava\b/) ); // Java |
112 | | -alert( "Hello, Java!".match(/\bHell\b/) ); // null (no match) |
113 | | -alert( "Hello, Java!".match(/\bJava!\b/) ); // null (no match) |
114 | | -``` |
115 | | - |
116 | | -Once again let's note that `pattern:\b` makes the searching engine to test for the boundary, so that `pattern:Java\b` finds `match:Java` only when followed by a word boundary, but it does not add a letter to the result. |
117 | | - |
118 | | -Usually we use `\b` to find standalone English words. So that if we want `"Java"` language then `pattern:\bJava\b` finds exactly a standalone word and ignores it when it's a part of `"JavaScript"`. |
119 | | - |
120 | | -Another example: a regexp `pattern:\b\d\d\b` looks for standalone two-digit numbers. In other words, it requires that before and after `pattern:\d\d` must be a symbol different from `\w` (or beginning/end of the string). |
121 | | - |
122 | | -```js run |
123 | | -alert( "1 23 456 78".match(/\b\d\d\b/g) ); // 23,78 |
124 | | -``` |
125 | | - |
126 | | -```warn header="Word boundary doesn't work for non-English alphabets" |
127 | | -The word boundary check `\b` tests for a boundary between `\w` and something else. But `\w` means an English letter (or a digit or an underscore), so the test won't work for other characters (like cyrillic or hieroglyphs). |
128 | | -``` |
129 | | - |
130 | | - |
131 | | -## Inverse classes |
132 | | - |
133 | | -For every character class there exists an "inverse class", denoted with the same letter, but uppercased. |
134 | | - |
135 | | -The "reverse" means that it matches all other characters, for instance: |
136 | | - |
137 | | -`\D` |
138 | | -: Non-digit: any character except `\d`, for instance a letter. |
139 | | - |
140 | | -`\S` |
141 | | -: Non-space: any character except `\s`, for instance a letter. |
142 | | - |
143 | | -`\W` |
144 | | -: Non-wordly character: anything but `\w`. |
145 | | - |
146 | | -`\B` |
147 | | -: Non-boundary: a test reverse to `\b`. |
148 | | - |
149 | | -In the beginning of the chapter we saw how to get all digits from the phone `subject:+7(903)-123-45-67`. |
150 | | - |
151 | | -One way was to match all digits and join them: |
| 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. |
152 | 88 |
|
153 | 89 | ```js run |
154 | 90 | let str = "+7(903)-123-45-67"; |
155 | 91 |
|
156 | 92 | alert( str.match(/\d/g).join('') ); // 79031234567 |
157 | 93 | ``` |
158 | 94 |
|
159 | | -An alternative, shorter way is to find non-digits `\D` and remove them from the string: |
160 | | - |
| 95 | +Uma maneira alternativa e mais curta é encontrar um `padrão:\D` não-dígito e removê-lo da string: |
161 | 96 |
|
162 | 97 | ```js run |
163 | 98 | let str = "+7(903)-123-45-67"; |
164 | 99 |
|
165 | 100 | alert( str.replace(/\D/g, "") ); // 79031234567 |
166 | 101 | ``` |
167 | 102 |
|
168 | | -## Spaces are regular characters |
| 103 | +## Um ponto é "qualquer caractere" |
169 | 104 |
|
170 | | -Usually we pay little attention to spaces. For us strings `subject:1-5` and `subject:1 - 5` are nearly identical. |
| 105 | +Um ponto `padrão:.` é uma classe de caractere especial que corresponde a "qualquer caractere, exceto uma nova linha". |
171 | 106 |
|
172 | | -But if a regexp doesn't take spaces into account, it may fail to work. |
173 | | - |
174 | | -Let's try to find digits separated by a dash: |
| 107 | +Por exemplo: |
175 | 108 |
|
176 | 109 | ```js run |
177 | | -alert( "1 - 5".match(/\d-\d/) ); // null, no match! |
| 110 | +alert( "Z".match(/./) ); // Z |
178 | 111 | ``` |
179 | 112 |
|
180 | | -Here we fix it by adding spaces into the regexp `pattern:\d - \d`: |
| 113 | +Ou no meio de uma regexp: |
181 | 114 |
|
182 | 115 | ```js run |
183 | | -alert( "1 - 5".match(/\d - \d/) ); // 1 - 5, now it works |
184 | | -``` |
| 116 | +let regexp = /CS.4/; |
185 | 117 |
|
186 | | -**A space is a character. Equal in importance with any other character.** |
| 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 | +``` |
187 | 122 |
|
188 | | -Of course, spaces in a regexp are needed only if we look for them. Extra spaces (just like any other extra characters) may prevent a match: |
| 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: |
189 | 124 |
|
190 | 125 | ```js run |
191 | | -alert( "1-5".match(/\d - \d/) ); // null, because the string 1-5 has no spaces |
| 126 | +alert( "CS4".match(/CS.4/) ); // null, sem correspondência porque não há caractere para o ponto |
192 | 127 | ``` |
193 | 128 |
|
194 | | -In other words, in a regular expression all characters matter, spaces too. |
195 | | - |
196 | | -## A dot is any character |
| 129 | +### Ponto como literalmente qualquer caractere com a flag "s" |
197 | 130 |
|
198 | | -The dot `"."` is a special character class that matches "any character except a newline". |
| 131 | +Por padrão, um ponto não corresponde ao caractere de nova linha `\n`. |
199 | 132 |
|
200 | | -For instance: |
| 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`: |
201 | 134 |
|
202 | 135 | ```js run |
203 | | -alert( "Z".match(/./) ); // Z |
| 136 | +alert( "A\nB".match(/A.B/) ); // null (sem correspondência) |
204 | 137 | ``` |
205 | 138 |
|
206 | | -Or in the middle of a regexp: |
| 139 | +Há muitas situações em que gostaríamos que um ponto significasse literalmente "qualquer caractere", incluindo a nova linha. |
207 | 140 |
|
208 | | -```js run |
209 | | -let reg = /CS.4/; |
| 141 | +É o que flag `padrão:s` faz. Se uma regexp possui, então um ponto `padrão:.` corresponde literalmente a qualquer caractere: |
210 | 142 |
|
211 | | -alert( "CSS4".match(reg) ); // CSS4 |
212 | | -alert( "CS-4".match(reg) ); // CS-4 |
213 | | -alert( "CS 4".match(reg) ); // CS 4 (space is also a character) |
| 143 | +```js run |
| 144 | +alert( "A\nB".match(/A.B/s) ); // A\nB (correspondência!) |
214 | 145 | ``` |
215 | 146 |
|
216 | | -Please note that the dot means "any character", but not the "absense of a character". There must be a character to match it: |
| 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". |
217 | 151 |
|
218 | 152 | ```js run |
219 | | -alert( "CS4".match(/CS.4/) ); // null, no match because there's no character for the dot |
| 153 | +alert( "A\nB".match(/A[\s\S]B/) ); // A\nB (match!) |
220 | 154 | ``` |
221 | 155 |
|
222 | | -### The dotall "s" flag |
| 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. |
223 | 157 |
|
224 | | -Usually a dot doesn't match a newline character. |
| 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 | +```` |
225 | 160 |
|
226 | | -For instance, this doesn't match: |
| 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. |
227 | 163 |
|
228 | | -```js run |
229 | | -alert( "A\nB".match(/A.B/) ); // null (no match) |
| 164 | +Mas se uma regexp não leva em consideração os espaços, ela pode falhar. |
230 | 165 |
|
231 | | -// a space character would match |
232 | | -// or a letter, but not \n |
233 | | -``` |
| 166 | +Vamos tentar encontrar dígitos separados por um hífen: |
234 | 167 |
|
235 | | -Sometimes it's inconvenient, we really want "any character", newline included. |
| 168 | +```js run |
| 169 | +alert( "1 - 5".match(/\d-\d/) ); // null, sem correspondência! |
| 170 | +``` |
236 | 171 |
|
237 | | -That's what `s` flag does. If a regexp has it, then the dot `"."` match literally any character: |
| 172 | +Vamos corrigi-lo adicionando espaços ao padrão regexp `padrão:\d - \d`: |
238 | 173 |
|
239 | 174 | ```js run |
240 | | -alert( "A\nB".match(/A.B/s) ); // A\nB (match!) |
| 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 |
241 | 178 | ``` |
242 | 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. |
243 | 183 |
|
244 | | -## Summary |
| 184 | +Em outras palavras, em uma expressão regular, todos os caracteres são importantes, espaços também. |
| 185 | +```` |
245 | 186 |
|
246 | | -There exist following character classes: |
| 187 | +## Resumo |
247 | 188 |
|
248 | | -- `pattern:\d` -- digits. |
249 | | -- `pattern:\D` -- non-digits. |
250 | | -- `pattern:\s` -- space symbols, tabs, newlines. |
251 | | -- `pattern:\S` -- all but `pattern:\s`. |
252 | | -- `pattern:\w` -- English letters, digits, underscore `'_'`. |
253 | | -- `pattern:\W` -- all but `pattern:\w`. |
254 | | -- `pattern:.` -- any character if with the regexp `'s'` flag, otherwise any except a newline. |
| 189 | +Existem as seguintes classes de caracteres: |
255 | 190 |
|
256 | | -...But that's not all! |
| 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`. |
257 | 198 |
|
258 | | -Modern JavaScript also allows to look for characters by their Unicode properties, for instance: |
| 199 | +...Mas isso não é tudo! |
259 | 200 |
|
260 | | -- A cyrillic letter is: `pattern:\p{Script=Cyrillic}` or `pattern:\p{sc=Cyrillic}`. |
261 | | -- A dash (be it a small hyphen `-` or a long dash `—`): `pattern:\p{Dash_Punctuation}` or `pattern:\p{pd}`. |
262 | | -- A currency symbol: `pattern:\p{Currency_Symbol}` or `pattern:\p{sc}`. |
263 | | -- ...And much more. Unicode has a lot of character categories that we can select from. |
| 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. |
264 | 202 |
|
265 | | -These patterns require `'u'` regexp flag to work. More about that in the chapter [](info:regexp-unicode). |
| 203 | +Também podemos pesquisar por essas propriedades. Isso requer a flag `padrão:u`, abordada no próximo artigo. |
0 commit comments