Manipular String com StringBuilder

19 respostas
jeovane.reges

Olá pessoal, bom dia.
Pessoal, minha dúvida é a seguinte:
Tenho uma String e gostaria que em certo ponto dela substituir uma subsequência por um valor qualquer.
Para tal, estou usando a classe StringBuilder.
Imaginem que eu tenha a seguinte String abaixo.

StringBuilder builder = new StringBuilder("SELECT ?Disease_name ?Drug_name\n" + " WHERE{\n" + " SERVICE <http://localhost:3030/diseasome/sparql> {\n" + " ?ds diseasome:name ?Disease_name.\n" + " FILTER(?Disease_name = ?:name)\n" + " }\n" + " SERVICE <http://localhost:3030/dailymed/sparql>{\n" + " ?dm dailymed:fullName ?Drug_name.\n" + " } \n" + " } limit 10");
Como vocês podem ver tenho uma subsequência constituida dos seguintes caracteres ?:name.
O que eu gostaria era de substituir essa subsequencia (?:name) por um valor qualquer que eu fosse passar por parâmetro.

Com o seguinte trecho do código abaixo, consigo pegar o inicio da subsequencia.

for (int i = 0; i < builder.length(); i++) { if (Character.toString(builder.toString().charAt(i)).startsWith("?") && Character.toString(builder.toString().charAt(i+1)).startsWith(":")){ //System.out.println(builder.toString().charAt(i) + "" + builder.toString().charAt(i+1)); System.out.println(builder.substring(i)); } }
No entanto, obtrer apenas o inicio da subsequencia não é o suficiente.
Uma que vez se eu mandar substituir a subsequencia do código acima, vai ser substituido tudo que fica após a subsequencia ?:name também.
Gostaria de saber se alguém pode me dar um dica se como que eu faço para substituir apenas a subsequencia ?:name e deixar todo o restante como estar.

Obs.: a subsequencia ?:name pode ser qualquer outro valor, como por exemplo ?:doenca, o que eu quero substituir é o que inicia com os caracteres ?:
Desde já obrigado pela atenção de todos.
Abraço.

19 Respostas

E

Que complicado, use String.replaceAll

jeovane.reges

Olá entanglement, bom dia.
String.replaceAll não funciona para o meu caso :confused:
Tenho que percorrer toda a String e encontrar a subsequencia da minha String que inicia com ?: e substitui-la por um valor que eu for passar.

Sendo que a subsequencia que quero substituir pode aparecer mais de uma vez.
Conhece nada que eu possa fazer que me ajude a fazer isso?
Obrigado.

E

Tudo depende de quantas variáveis você precisa trocar nesse código.

Digamos que você só tenha a variável “name”, ou seja, “?:name”. Nesse caso, é ridiculamente simples, porque você teria algo como:

String s = "SELECT ?Disease_name ?Drug_name\n" +  
"            WHERE{\n" +  
"                SERVICE <http://localhost:3030/diseasome/sparql> {\n" +  
"                    ?ds diseasome:name ?Disease_name.\n" +  
"                    FILTER(?Disease_name = ?:name)\n" +  
"                }\n" +  
"                SERVICE <http://localhost:3030/dailymed/sparql>{\n" +  
"                    ?dm dailymed:fullName ?Drug_name.\n" +  
"                } \n" +  
"            } limit 10".replaceAll ("?:name", "\"Mitochondrial disease\"");

Entretanto, se você tiver várias variáveis, aí você precisa de algo um pouco mais poderoso.

juno.rr

não é o mais recomendado, mas vc pode usar um for pra procurar e substituir o conteúdo.

String newString ...
String repl = "?:name";
int index = 0;
for(int i = 0; i &lt; builder.length(); i++) {
  if(builder.substring(i, (i + repl.length())).equals(repl)) {
    builder.delete(i, (i + repl.length()));
    builder.insert(i, newString);
  }
}
jeovane.reges

Olá juno.rr, boa tarde.
Poderia até ser uma solução sua dica, mas acontece que nem sempre repl será necessariamente “?:name”.

jeovane.reges

Pois é entanglement, as variáveis inicializadas com : ? podem aparecerem mais de uma vez. Na verdade, a String que demonstrei acima é uma consulta em SPARQL parametrizada.
Sabe me indicar que tipo classe mais poderosa seria essa que eu poderia usar?
Obrigado

juno.rr

Você pode usar um array para todas as possibilidades, tanto para o replace quanto para newString.
Por exemplo:

String newString ...  
String[] repl = { "?:name", "?:another", ... };
int index = 0;
for(int j = 0; j &lt; repl.length; j++) {
  for(int i = 0; i &lt; builder.length(); i++) {  
    if(builder.substring(i, (i + repl[j].length())).equals(repl[j])) {  
      builder.delete(i, (i + repl[j].length()));  
      builder.insert(i, newString);  
    }  
  }  
}
jeovane.reges

O que acontece é que pode vir qualquer coisa, ou seja, não tem como ter um controle.
Por isso o ideal seria que fosse percorrido toda a String em busca de alguma subsequencia que iniciasse com “: ?..” e então substitui-la.
Obrigado pela ajuda juno.rr

jeovane.reges
Olá wellington.nogueira, bom dia. Para trabalhar com SPARQL utilizo a biblioteca Jena. Conhece ela? Eu conseguir uma maneira de "contornar" esse problema, onde pego as variável que receberão os parâmetros, coloca-as numa lista pra então fazer a substituição. O código ficou da seguinte maneira abaixo.
List<String> parameterList = new ArrayList<String>();

ParameterizedSparqlString sparqlString  = new ParameterizedSparqlString(queryString);
for (int i = 0; i < parameterList.size(); i++) {
    String[] setLiteral = parameterList.get(i).split(",", 2);
    if (urlValidator.isValid(setLiteral[1])) {
        sparqlString.setIri(setLiteral[0], setLiteral[1]);
    } else {
        sparqlString.setLiteral(setLiteral[0], setLiteral[1]);
    }
}

query = QueryFactory.create(sparqlString.toString());
queryExecution = QueryExecutionFactory.sparqlService(this.endpoint, query);
ResultSet result = queryExecution.execSelect();
jeovane.reges
Vou dar uma analisada nesse código e fazer uns testes :-D Obrigado pela ajuda e atenção wellington.nogueira
wellington.nogueira:
void teste() {
		try {
			metodo(new String[] { "?:name", "?:outroparametro" }, new String[] {
					"joao", "vale-tudo" });
		} catch (InvalidArgumentsException e) {
			e.printStackTrace();
		}
	}

	void metodo(String[] parametros, String[] valores)
			throws InvalidArgumentsException {
		if (parametros.length != valores.length)
			throw new InvalidArgumentsException(
					"Quantidade de parametros não bate com quantidade de valores");
		String[] newString = valores;
		String[] repl = parametros;
		int index = 0;
		for (int j = 0; j < repl.length; j++) {
			for (int i = 0; i < builder.length(); i++) {
				if (builder.substring(i, (i + repl[j].length()))
						.equals(repl[j])) {
					builder.delete(i, (i + repl[j].length()));
					builder.insert(i, newString[i]);
				}
			}
		}
	}
jeovane.reges

De boa wellington.nogueira qualquer inconsistência tento corrigir o código :smiley:
Obrigado.

freakazoid

Eae galera,

Todas as vezes que me deparo com um problema desses a primeiro coisa que me vem em mente é uma expressão regular.
Segue abaixo minha contribuição:

String texto = "...?:name.....?:name.....?:name";

		System.out.println(texto);
		Pattern padrao = Pattern.compile("[?]:name");
		Matcher localizador = padrao.matcher(texto);
		String resultado = "";
		while (localizador.find()) {

			resultado = localizador.replaceFirst(" \">>TESTE<<\"");
			localizador = padrao.matcher(resultado);

		}
		System.out.println(resultado);

Espero que tenha ajudado! Abs!!

jeovane.reges

Olá freakazoid, obrigado pela resposta.
Irei testa-la também :smiley: … é sempre bom ter mais de uma opção para testes.
Muito obrigado :slight_smile:

freakazoid

jeovane.reges:
Olá freakazoid, obrigado pela resposta.
Irei testa-la também :smiley: … é sempre bom ter mais de uma opção para testes.
Muito obrigado :-)

Por nada maninho!

Apenas complementando a resposta, na linha:

Pattern padrao = Pattern.compile("[?]:name");

O caractere ‘?’ é um meta caractere em uma expressão regular, portanto para usá-lo no seu sentido literal foi necessário colocá-lo dentro de uma lista []. Vc tbm poderia usar o .

[?] é igual a ?

Eu prefiro [?].

Abs!

jeovane.reges

Valeu freakazoid.
Não sabia dessa de usar colchetes, sempre usava a barra de escape ("").
Obrigado mais uma vez :slight_smile:

freakazoid

A solução com apenas uma linha:

texto = texto.replaceAll("[?]:name", " \">>TESTE<<\"");
WellingtonRamos

Por acaso não é possível utilizar JDBC com esse SPARQL e utilizar-se de PrepareStatement?

No google há algumas opções como esta: https://code.google.com/p/jdbc4sparql/

WellingtonRamos

jeovane.reges:
O que acontece é que pode vir qualquer coisa, ou seja, não tem como ter um controle.
Por isso o ideal seria que fosse percorrido toda a String em busca de alguma subsequencia que iniciasse com “: ?..” e então substitui-la.
Obrigado pela ajuda juno.rr
A solução que o @juno.rr é uma boa para você mas eu faria uma alteração:

void teste() {
		try {
			metodo(new String[] { "?:name", "?:outroparametro" }, new String[] {
					"joao", "vale-tudo" });
		} catch (InvalidArgumentsException e) {
			e.printStackTrace();
		}
	}

	void metodo(String[] parametros, String[] valores)
			throws InvalidArgumentsException {
		if (parametros.length != valores.length)
			throw new InvalidArgumentsException(
					"Quantidade de parametros não bate com quantidade de valores");
		String[] newString = valores;
		String[] repl = parametros;
		int index = 0;
		for (int j = 0; j < repl.length; j++) {
			for (int i = 0; i < builder.length(); i++) {
				if (builder.substring(i, (i + repl[j].length()))
						.equals(repl[j])) {
					builder.delete(i, (i + repl[j].length()));
					builder.insert(i, newString[i]);
				}
			}
		}
	}
WellingtonRamos

jeovane.reges:
Vou dar uma analisada nesse código e fazer uns testes :smiley:
Obrigado pela ajuda e atenção wellington.nogueira
[/quote]Por nada. Só para comentar, não cheguei a testar o código, apenas modifiquei o anterior incluindo minhas alterações.

Criado 29 de abril de 2013
Ultima resposta 30 de abr. de 2013
Respostas 19
Participantes 5