4

I have to replace in a string the characters before and after the occurrence of the matched word.

I was wondering:

1. if the functionality is better when I use a regex or when we use indexOf, loops etc.?

2. what is considered a more readable code: regex or using indexOf, iterating through the string, etc.?

3. in means of time complexity, in which way the complexity is decreased.

Just to clarify, what I am asking is what is better using regex or just doing string manipulation. See my questions above

Gale
  • 388
  • 2
  • 14
  • Can you show us what the string and its replacement are? – Tim Biegeleisen Nov 10 '19 at 14:26
  • @TimBiegeleisen, added an example. – Gale Nov 10 '19 at 14:35
  • Probably the most efficient you could do would be to simply matching [`(abc)|.`](https://regex101.com/r/JlRaru/5) and while going through matches, if group one is set, append `group(1)` to a new string, else append `*`. Also see [The Best Regex Trick](https://www.rexegg.com/regex-best-trick.html). Or you could do one `replaceAll()` with a [`\G`](https://www.regular-expressions.info/continue.html) based pattern like [`(?:(?<=abc)|\G)(?!abc).`](https://regex101.com/r/JlRaru/1) – bobble bubble Nov 10 '19 at 22:49

3 Answers3

2

Here is an iterative solution using a formal Java regex pattern matcher:

String input = "abc1111abc3434";
StringBuffer buffer = new StringBuffer();
String pattern = "((?!abc).)*abc";
Pattern r = Pattern.compile(pattern);
Matcher m = r.matcher(input);
while (m.find()) {
    String replace = m.group(0).replaceAll(".", "*");
    replace = replace.substring(0, replace.length()-3) + "abc";
    m.appendReplacement(buffer, replace);
}
int length = buffer.length();
m.appendTail(buffer);
String result = buffer.substring(0, length) + buffer.substring(length).replaceAll(".", "*");
System.out.println(result);

This prints:

abc****abc****

The trick being used here is the following regex pattern:

((?!abc).)*abc

This will match any content which is not the sequence abc, but which ends in abc. That is, the first portion of this pattern is the actual content you want to mask with ***. At each match, we append to the StringBuffer the masked content followed by the abc marker. Note that this creates an edge case. After all replacements have been made, there might be a tail of non abc content. In this case, we just mask the entire substring and append to the StringBuffer.

Tim Biegeleisen
  • 387,723
  • 20
  • 200
  • 263
-1

Invokve close() method, once your usage of the resource is completed.

This ensures the resource is closed, and clears the allocated memory.

In your case it will be,

input1.close();

and

input2.close();

After your both results are printed.

Detailed API for scanner (JDK8) : https://docs.oracle.com/javase/8/docs/api/java/util/Scanner.html

-1
String str ="abc1111abc3434";
System.out.println( str.replaceAll("[^\"abc\"]", "*"));
Jigar Gajjar
  • 151
  • 1
  • 11