specific online examples java regex set

java - online - Emita con el siguiente fragmento de boundary matchers regex(/ b)



regex r (2)

El problema es que no está creando la expresión regular correcta para reemplazar las palabras en el conjunto.

"//b"+toDelete+"//b" producirá esta cadena /b[end, something]/b que no es lo que necesita.

Para solucionarlo, puedes hacer algo como esto:

for(String del : toDelete){ line = line.replaceAll("//b"+del+"//b", ""); }

Lo que hace es pasar por el conjunto, producir una expresión regular de cada palabra y eliminar esa palabra de la line cadena.

Otro enfoque será producir una expresión regular única a partir de todas las palabras del conjunto.

P.ej:

String regex = ""; for(String word : toDelete){ regex+=(regex.isEmpty() ? "" : "|") + "(//b"+word+"//b)"; } .... line = line.replace(regex, "");

Esto debería producir una expresión regular que se parece a esto: (/bend/b)|(/bsomething/b)

Mi entrada:

1. end 2. end of the day or end of the week 3. endline 4. something 5. "something" end

En función de las discusiones anteriores, si intento reemplazar una sola cadena con este fragmento, se eliminan las palabras apropiadas de la línea con éxito.

public class DeleteTest { public static void main(String[] args) { // TODO Auto-generated method stub try { File file = new File("C:/Java samples/myfile.txt"); File temp = File.createTempFile("myfile1", ".txt", file.getParentFile()); String delete="end"; BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(file))); PrintWriter writer = new PrintWriter(new OutputStreamWriter(new FileOutputStream(temp))); for (String line; (line = reader.readLine()) != null;) { line = line.replaceAll("//b"+delete+"//b", ""); writer.println(line); } reader.close(); writer.close(); } catch (Exception e) { System.out.println("Something went Wrong"); } } }

Mi salida Si uso el fragmento de arriba: (También mi salida esperada)

1. 2. of the day or of the week 3. endline 4. something 5. "something"

Pero cuando incluyo más palabras para eliminar, y para ese propósito cuando uso Set, utilizo el siguiente fragmento de código:

public static void main(String[] args) { // TODO Auto-generated method stub try { File file = new File("C:/Java samples/myfile.txt"); File temp = File.createTempFile("myfile1", ".txt", file.getParentFile()); BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(file))); PrintWriter writer = new PrintWriter(new OutputStreamWriter(new FileOutputStream(temp))); Set<String> toDelete = new HashSet<>(); toDelete.add("end"); toDelete.add("something"); for (String line; (line = reader.readLine()) != null;) { line = line.replaceAll("//b"+toDelete+"//b", ""); writer.println(line); } reader.close(); writer.close(); } catch (Exception e) { System.out.println("Something went Wrong"); } }

Obtengo mi salida como: (Simplemente elimina el espacio)

1. end 2. endofthedayorendoftheweek 3. endline 4. something 5. "something" end

¿Pueden ayudarme en esto?

Haga clic aquí para seguir el hilo


Necesita crear un grupo de alternancia del conjunto con

String.join("|", toDelete)

y usar como

line = line.replaceAll("//b(?:"+String.join("|", toDelete)+")//b", "");

El patrón se verá como

/b(?:end|something)/b

Vea la demostración de expresiones regulares . Aquí, (?:...) es un grupo no captor que se usa para agrupar varias alternativas sin crear un búfer de memoria para la captura (no lo necesita ya que elimina las coincidencias).

O mejor, compila la expresión regular antes de ingresar al ciclo:

Pattern pat = Pattern.compile("//b(?:" + String.join("|", toDelete) + ")//b"); ... line = pat.matcher(line).replaceAll("");

ACTUALIZAR :

Para permitir la coincidencia de "palabras" completas que pueden contener caracteres especiales, se necesita Pattern.quote las palabras para escapar de esos caracteres especiales, y luego debe usar límites de palabras no ambiguos, (?<!/w) lugar de la inicial /b para asegurarse de que no hay una palabra char antes y (?!/w) mirada negativa en lugar de la final /b para asegurarse de que no haya palabras char después de la coincidencia.

En Java 8, puedes usar este código:

Set<String> nToDel = new HashSet<>(); nToDel = toDelete.stream() .map(Pattern::quote) .collect(Collectors.toCollection(HashSet::new)); String pattern = "(?<!//w)(?:" + String.join("|", nToDel) + ")(?!//w)";

La expresión regular se verá como (?<!/w)(?:/Q+end/E|/Qsomething-/E)(?!/w) . Tenga en cuenta que los símbolos entre /Q y /E se analizan como símbolos literales .