 VB
2005 - Mais Algumas palavras sobre Strings
VB
2005 - Mais Algumas palavras sobre Strings
Para começar vamos lembrar que uma String pode ser considerada um conjunto de caracteres Unicode seqüenciais que são usados para representar um texto.
Desta forma um objeto String é uma coleção de objetos
System.Char e o valor do objeto String é o conteúdo da coleção
seqüencial, e esse valor é imutável. Sim eu disse IMUTÁVEL...
Um objeto String é imutável pois é considerado somente leitura visto que o seu valor não pode ser modificado uma vez que ele tenha sido criado.
Não se engane, métodos que parecem modificar um objeto String 
na verdade retornam um novo objeto String que contém a modificação.

Se for necessário mesmo modificar o conteúdo real de um objeto String você deve usar a classe System.Text.StringBuilder
Para saber mais acompanhe o artigo : VB .NET - StringBuilder : tratando Strings de modo mais eficiente.
A classe String fornece diversos membros para comparar objetos String , retornar o índice de um caractere ou seqüência, copiar o valor de um String objeto, combinar seqüências, modificar o valor de seqüência, formatar números, datas e horas, ou valores de enumeração em uma seqüência, e normalizar uma seqüência.
Veja uma introdução ao assunto no artigo : VB.NET - Strings um novo enfoque
1- Comparando Strings
Podemos comparar Strings usando 3 métodos diferentes:
a-) O método Compare
Compara duas strings e retorna um valor inteiro. O valor retornado do método Compare pode ser :
| Valor | Significado | 
| Menor que zero ( > 0) | Quando a string é menor que a segunda | 
| Zero ( = 0 ) | Quando ambas as strings são iguais | 
| Maior que Zero ( < 0) | Quando a primeira string é maior que a segunda | 
| Compare | 
| '
    
    
    'comparando duas strings: 
    str1 e str2
    
    
    Dim str1 
    As 
    String = 
    "bbb"
    
    
    Dim str2 
    As 
    String = 
    "BBB"
    
    
    Dim resultado 
    As Int16 = 
    String.Compare(str1, 
    str2) ListBox1.Items.Add("Primeiro resultado : str1= " + str1 + " str2=" + str2 + vbTab + "=> " + resultado.ToString()) str2 ="aaa" resultado =String.Compare(str1, str2) ListBox1.Items.Add("Segundo resultado str1= " + str1 + " str2=" + str2 + vbTab + "=> " + resultado.ToString()) str1 ="aaa" resultado =String.Compare(str1, str2) ListBox1.Items.Add("Terceiro resultado str1= " + str1 + " str2=" + str2 + vbTab + "=> " + resultado.ToString()) 
 | 
| Resultado:  | 
b-) O Método CompareOrdinal
Compara dois objetos Strings avaliando os valores numéricos dos objetos correspondentes Char em cada seqüência.
| Nome | Descrição | 
|---|---|
| String.CompareOrdinal (String, String) | Compara dois objetos String especificados avaliando os valores numéricos dos objetos Char correspondentes em cada seqüência. | 
| String.CompareOrdinal (String, Int32, String, Int32, Int32) | Compara substrings dos dois objetos Strings especificados, avaliando os valores numéricos dos objetos Char correspondentes em cada subseqüência. | 
| CompareOrdinal | 
| 'comparando duas strings: 
    str1 e str2
    
    
    Dim str1 
    As 
    String = 
    "bbb"
    
    
    Dim str2 
    As 
    String = 
    "BBB"
    
    
    Dim resultado 
    As Int16 = 
    String.CompareOrdinal(str1, 
    str2) ListBox1.Items.Add("Primeiro resultado : str1= " + str1 + " str2=" + str2 + vbCrLf + "=> " + resultado.ToString()) str2 ="aaa" resultado =String.CompareOrdinal(str1, str2) ListBox1.Items.Add("Segundo resultado str1= " + str1 + " str2=" + str2 + vbCrLf + "=> " + resultado.ToString()) str1 ="aaa" resultado =String.CompareOrdinal(str1, str2) ListBox1.Items.Add("Terceiro resultado str1= " + str1 + " str2=" + str2 + vbCrLf + "=> " + resultado.ToString()) | 
| Resultado:  | 
c-) Método CompareTo
Compara esta instância com um objeto especificado ou String e retorna uma indicação de seus valores relativos
| Método | Descrição | 
|---|---|
| String.CompareTo (Object) | Compara esta instância com um Object. | 
| String.CompareTo (String) | Compara esta instância com um objeto String especificado. | 
| CompareTo | 
| 'comparando duas 
    strings: str1 e str2
    
    
    Dim str1 
    As 
    String = 
    "bbb"
    
    
    Dim str2 
    As 
    String = 
    "BBB"
    
    
    Dim resultado 
    As 
    Int16 = str1.CompareTo(str2) MsgBox("Primeiro resultado : str1= " + str1 + " str2=" + str2 + vbCrLf + "=> " + resultado.ToString()) str2 ="aaa" resultado = str1.CompareTo(str2) MsgBox("Segundo resultado str1= " + str1 + " str2=" + str2 + vbCrLf + "=> " + resultado.ToString()) str1 ="aaa" resultado = str1.CompareTo(str2) MsgBox("Terceiro resultado str1= " + str1 + " str2=" + str2 + vbCrLf + "=> " + resultado.ToString()) | 
| Resultado:  | 
O método Compare executa uma comparação lingüística enquanto 
o método CompareOrdinal executa uma comparação ordinal.  
Desta forma se a
cultura atual for inglês americano, o Compare método
considera ' a ' menor que ' A ' enquanto o método CompareOrdinal considera  ' a ' maior que ' A '.
O método CompareTo é um método de instância e compara o valor (string ou 
objeto) com a instância da string. Os valores retornados são os mesmos que o 
método Compare.
2- Criando uma string com N caracteres idênticos
Para criar uma nova string de caracteres repetidos você pode usar um dos construtores da classe String que aceita um caractere a ser repetido e um valor indicando o número de repetições. Assim para repetir o asterisco 100 vezes você pode fazer:
| Dim asteristicos As New String("*"c, 100) msgbox(asteristicos) | 
|  | 
O VB 2005 também fornece uma segunda forma de criar strings com caracteres repetidos. A função StrDup() que é idêntica a função String() encontrada no VB 6 também efetua a mesma operação:
| asteristicos =
    StrDup(100, "*") msgbox(asteristicos) | 
|  | 
Note a diferença na ordem dos parâmetros entre o construtor string e a chamada da função. Felizmente o VB 2005 e o VS 2005 possuem o recurso de IntelliSense que lhe mostra a ordem dos parâmetros a usar.
3- Criando um string pela repetição da strings N vezes
Para criar uma sequência de caracteres repetidos você pode usar uma StringBuilder. Assim para criar uma sequência de * e # podemos fazer:
| Dim linha As New System.Text.StringBuilder For contador As Integer = 1 To 25 linha.Append("*#") Next countador MsgBox(linha.ToString()) | 
|  | 
Você já deve esta cansado de saber que strings em .NET são imutáveis , o que significa que uma vez criadas elas permanecem em um local da memória e não podem ser modificadas. Todas as funções que aparentam alterar o conteúdo de uma string estão na verdade fazendo novas cópias da string original. Para criar strings concatenadas isto pode ser um problema .
O objeto StringBuilder resolve em parte do problema da concatenação pois permite a modificação dinâmica de um buffer contendo uma sequência de caracteres string sem a necessidade de constantemente realocar os objetos strings. Se o espaço do buffer alocado não for suficiente o StringBuilder dobra o número de bytes para o caractere e ele faz isto quantas vezes for preciso para manipular strings e os caracteres a serem concatenados.
4- Extraindo trechos de uma string maior
O Visual Basic 2005 possui um método chamado Substring() que fornece uma alternativa as tradicionais funções Left(), Mid(), e Right() do VB6.(Estas funções ainda estão presentes no VB 2005 por questão de compatibilidade). Para emular estas funções defina os parâmetros do método Substring de forma adequada conforme exemplo a seguir:
| Private 
    Sub Button5_Click(ByVal 
    sender As System.Object,
    ByVal e 
    As System.EventArgs)
    Handles 
    Button5.Click Dim frase As String = "Ser ou não ser eis a questão. Shakespeare" ' 0123456789012345678901234567890123456789012 'VB6 ----- Left(frase, 3) … resultado "Ser" ListBox2.Items.Add(frase.Substring(0, 3))' VB6 ----- Mid(frase, 22, 7) … resultado "questão" ListBox2.Items.Add(frase.Substring(21, 7)) 'VB6 ----- Mid(frase, 31) … resultado "Shakespeare" ListBox2.Items.Add(frase.Substring(30)) 'VB6 ----- Right(frase, 11) … resultado "Shakespeare" ListBox2.Items.Add(frase.Substring(frase.Length - 11)) End Sub | 
Perceba que no VB 2005 o primeiro caractere na string começa na posição 0 e não na posição 1 como no VB6.
5- Convertendo strings para caracteres e vice-versa
Se você precisar trabalhar com caracteres individuais em uma string alterando o seu lugar na memória você pode usar o Ctype para converter a string para um array de caracteres modificar os caracteres e então converter diretamente o array de caractere de volta para a string. Vejamos um exemplo:
| Dim frase As
    String = 
    "Ser ou não ser eis a questão. Shakespeare"
    
    
    Dim charArray() As
    Char = CType(frase,
    Char()) charArray(29) = "!"c Dim resultado As String = New String(charArray) ListBox2.Items.Add(resultado) | 
|  | 
Neste exemplo, a string é convertida para um array de caracteres usando a função de conversão Ctype().
Podemos então alterar facilmente o array, como por exemplo incluindo um ponto de exclamação no final da frase. A seguir o array é então recombinado em uma string passando-a para o construtor da classe que usa um array de caracteres para iniciar uma nova string.
Existe outra forma de acessar os caracteres individuais em uma string, mas ele é somente leitura e você não pode usá-lo para modificar a string:
| MsgBox(frase.Chars(19)) | 
Toda a string possui uma propriedade Chars() que permite o acesso a um caractere pelo índice. O primeiro caractere inicia na posição 0 , assim Chars(19) retorna o caractere no índice 20 (letra a).
6- Convertendo strings para array de bytes
Você pode converter string para bytes e retornar para string a partir de um array de bytes. Com esta operação você pode trabalhar com dados binários exatos.
Para efetuar a conversão você usa o método Enconding do namespace System.Text. Se você sabe que a string a ser convertida é composta inteiramente de caracteres ASCII , você pode usar o enconding UTF8 para minimizar o tamanho do array de bytes.
A codificação Unicode que resulta em dois bytes por caractere (ao invés de um) pode ser usada para garantir que os dados não sejam perdidos quando estas conversões forem realizadas:
Vejamos um exemplo que mostra a codificação usando métodos UTF8 e Unicode:
| Dim frase As
    String = 
    "Ser ou não ser eis a questão. Shakespeare"
    
    
    Dim bytes() As
    Byte
    
    
    Dim resultado As
    String
    
    
    ' ----- Assumindo que todos os 
    caracteres são ASCII. bytes = System.Text.Encoding.UTF8.GetBytes(frase) bytes(29) = 33 ' ponto de exclamação em ASCII 
 MsgBox(resultado) 
     bytes = System.Text.Encoding.Unicode.GetBytes(frase) bytes(58) = 63 ' ponto de interrogação em ASCII 
 MsgBox(resultado) 
 MsgBox(resultado) 
 | 
Quando você usa a codificação UTF8 , o número de bytes no array é o mesmo que o número de bytes na string. No exemplo estamos alterando o caractere . da posição 29 da string para um ponto de exclamação e a seguir exibindo o resultado.
Um array de bytes com codificação Unicode contém duas vezes mais bytes que o número de caracteres na string original visto que os caracteres Unicodes são representados por 16 bits cada (ou dois bytes) em tamanho. É por isto que a posição do byte 58 é a posição do . ponto final , pois cada caracteres consome dois bytes no array .
7- Contando palavras em uma string
Você pode usar a função Split() para separar a string a cada caractere espaço. O comprimento do array resultado é uma boa aproximação do número de palavras na string.
Vejamos o código a seguir que faz esta operação:
| Dim frase As
    String = 
    "Ser ou não ser eis a questão. Shakespeare" Dim contaPalavra As Integer = Split(frase, Space(1)).Length ListBox1.Items.Add(frase) ListBox1.Items.Add("Número de palavras: " & contaPalavra.ToString) | 
|  | 
Imprecisões podem ocorrer se existirem múltiplos espaço entre algumas palavras na string ou se existiram caracteres tab na string. Você pode efetuar uma eliminação prévia destas ocorrências. A seguir substituir espaços duplos por espaços simples.
| DoWhile (frase.IndexOf(Space(2)) >= 0) frase = frase.Replace(Space(2), Space(1)) Loop | 
De forma semelhante você pode usar o método Replace para
substituir todos os tabs com espaço. Quando mais precisão você
desejar mais código você vai ter que escrever...
9- Substituindo strings
Para encontrar e substituir uma ocorrência de uma string em outra string você pode usar o método Replace().
Veja o exemplo a seguir a substituição do caractere er por ENDO:
| Dim frase
    As String = 
    "Ser ou não ser eis a 
    questão. Shakespeare"
    Dim resultado
    As String = frase.Replace("er",
    "ENDO") MsgBox(resultado) | 
|  | 
10 - Inserindo um caractere em uma string
O método Insert() do objeto String é sobrecarregado para aceitar um caractere ou uma string a ser inserida em uma dada posição da string. Para incluir uma virgula depois da palavra eis use o seguinte código:
| Dim frase
    As String = 
    "Ser ou não ser eis a 
    questão. Shakespeare"
    Dim resultado
    As String = frase.Insert(18, 
    ","c) MsgBox(resultado) | 
|  | 
Neste caso o caractere é inserido depois da posição 19 da string, ou apenas depois do caractere s de eis. Você pode inserir um caractere na primeira posição de uma string usando o índice 0 e no fina da string usando o valor de comprimento da string
O código abaixo inclui a palavra "fim ".
| Dim frase
    As String = 
    "Ser ou não ser eis a 
    questão. Shakespeare" frase = frase.Insert(29, "fim") MsgBox(frase) | 
11- Invertendo uma string
Se você deseja inverter uma string use a função StrReverse():
| Dim frase
    As String = 
    "Ser ou não ser eis a 
    questão. Shakespeare"
    Dim invertida
    As String = 
    StrReverse(frase) MsgBox(invertida) | 
|  | 
Uma outra forma de inverter uma string é processar os caracteres via código. No exemplo abaixo percorremos a string na ordem reversa e anexamos cada caractere encontrado em uma nova instancia de um StringBuilder:
| Dim frase
    As String = 
    "Ser ou não ser eis a 
    questão. Shakespeare"
    Dim contador
    As 
    Integer Dim resultado As New System.Text.StringBuilder(frase.Length) For contador = frase.Length - 1 To 0 Step -1 resultado.Append(frase.Chars(contador)) Next contador Dim invertida
    As String = 
    resultado.ToString() | 
O construtor sobrecarregado para StringBuilder aceita um parâmetro opcional definindo a capacidade que a StringBuilder usará para o seu buffer interno.
Desde que nos sabermos que string inversa terá o 
mesmo
tamanho da original, a capacidade pode ser definida exatamente
para a quantidade necessária. Isto previne a stringBuilder 
de ter o dobro de capacidade.
Como a esta altura do artigo já temos muito informação 
sobre strings eu vou deixar para falar mais sobre os demais recursos em outro 
artigo senão fica muito cansativo...
Até o próximo artigo VB.NET...
José Carlos Macoratti