Reputation: 333
I have a string that can be in any of the format like below:
'xyz','abc' //after conversion --> 'abc'
'abc','xyz' //after conversion --> 'abc'
'xyz' //after conversion -->
'abc','xyz','abc' //after conversion --> 'abc','abc'
In this I have to remove 'xyz'
and if it has any leading or trailing comma.
Please suggest how can I achieve this with regular expression.
Thanks
Upvotes: 0
Views: 739
Reputation: 28977
Regex alone is not very well equipped for this task. However, you can do the following:
"'abc', 'xyz'"
, for example. You can use the regex \s*,\s*
for that.Usign Java 8 Stream operations, this can be short:
String[] split = str.split(("\\s*,\\s*")); //1. split into separate strings
String result = Arrays.stream(split) //turn to stream
.filter(chunk -> !"'xyz'".equals(chunk)) //2. remove anything you don't want
.collect(Collectors.joining(",")); //3. convert back to comma separated list
The .filter
predicate can be changed to whatever suits you - if you only want to match "'abc'"
then you can use chunk -> "abc'".equals(chunk)
or you can use .contains
or equalsIgnoreCase
, or even regex.
It might be worth extracting the filter rule out into a separate Predicate, so you can more easily change it, when needed
Predicate<String> filterRule = chunk -> !"'xyz'".equals(chunk);
/* ... */
.filter(filterRule)
/* ... */
Although if we examine this "'xyz'".equals
is already a predicate itself, and predicates can be negated, so you don't need to write a whole lambda for this but just re-use the methods as functional interfaces:
Predicate<String> stuffWeDontWant = "'xyz'"::equals;
Predicate<String> filterRule = stuffWeDontWant.negate();
This can all be inlined but it's a bit ugly, as you have to cast it into the proper predicate to negate it
Predicate<String> filterRule = ((Predicate<String>) "'xyz'"::equals).negate();
The final thing can look like this:
Predicate<String> filterRule = ((Predicate<String>) "'xyz'"::equals).negate();
String result = Arrays.stream(str.split(("\\s*,\\s*")))
.filter(filterRule)
.collect(Collectors.joining(","));
So now you can more easily change whatever your filter rule is. You can even re-use this for any kind of list by just passing different predicate to use as a filter.
A non-Java 8 or non-Stream way to do the same to do the following:
String[] split = str.split(("\\s*,\\s*")); //1. split into separate strings
List<String> list = new ArrayList<>(Arrays.asList(split));//convert into an ArrayList to allow removing
list.removeAll(Collections.singleton("'xyz'"));//2. remove anything you don't want
String result = String.join(",", list); //3. convert back to comma separated list
This approach can still be mixed with using a Predicate by using .removeIf()
but this time it has to match exactly what you don't want:
list.removeIf("'xyz'"::equals);
/* or */
list.removeIf("'xyz'"::equalsIgnoreCase);
/* or */
list.removeIf("'xyz'"::startsWith);
/* or */
list.removeIf("'xyz'"::contains);
/* or */
list.removeIf("'xyz'"::endsWith);
/* or */
list.removeIf(Pattern.compile("'(xy?z)*'").asPredicate());
/* ...and so on... */
Upvotes: 0
Reputation: 44824
You could chain some String::replace
methods
String str = "'abc','xyz','abc'";
str = str.replace (",'xyz'", "").replace("'xyz',", "").replace("'xyz'", "");
output
'abc','abc'
Upvotes: 1