Java Split on Spaces and Special Characters - java

I am trying to split a string on spaces and some specific special characters.
Given the string "john - & + $ ? . # boy"
I want to get the array:
array[0]="john";
array[1]="boy";
I've tried several regular expressions and gotten no where. Here is my current stab:
String[] terms = uglString.split("\\s+|[\\-\\+\\$\\?\\.#&].*");
Which preserves "john" but not "boy". Can anyone get me the rest of this?

Just use:
String[] terms = input.split("[\\s#&.?$+-]+");
You can put a short-hand character class inside a character class (note the \s), and most meta-character loses their meaning inside a character class, except for [, ], -, &, \. However, & is meaningful only when comes in pair &&, and - is treated as literal character if put at the beginning or the end of the character class.
Other languages may have different rules for parsing the pattern, but the rule about - applies for most of the engines.
As #Sean Patrick Floyd mentioned in his answer, the important thing boils down to defining what constitute a word. \w in Java is equivalent to [a-zA-Z0-9_] (English letters upper and lower case, digits and underscore), and therefore, \W consists of all other characters. If you want to consider Unicode letters and digits, you may want to look at Unicode character classes.

You could make your code much easier by replacing your pattern with "\\W+" (one or more occurrences of a non-word character. (This way you are whitelisting characters instead of blacklisting, which is usually a good idea)
And of Course things could be made more efficient by using Guava's Splitter class

Try out this.....
Input.replace("-&+$?.#"," ").split(" ");

Breaking then step by step:
For your case, you replace non-word chars (as pointed out). Now you might want to preserve the spaces for an easy String split.
String ugly = "john - & + $ ? . # boy";
String words = ugly.replaceAll("[^\\w\\s]", "");
There are a lot of spaces in the resulting String which you might want to generally trim to just 1 space:
String formatted = words.trim().replaceAll(" +", " ");
Now you can easily split the String into the words to a String Array:
String[] terms = formatted.split("\\s");
System.out.println(terms[0]);

to add to what have been said about Splitter, you can do something of this sort:
String str = "john - & + $ ? . # boy";
Iterable<String> ttt = Splitter.on(Pattern.compile("\\W")).trimResults().omitEmptyStrings().split(str);

Use this format.
String s = "john - & + $ ? . # boy";
String reg = "[!_.',#? ]";
String[] res = s.split(reg);
here include every character that you want to split inside the [ ] brackets.

You can use something like below
arrayOfStringType=string.split(" |'|,|.|//+|_");
'|' will work as an or operator here.

Related

String.split() not working as intended

I'm trying to split a string, however, I'm not getting the expected output.
String one = "hello 0xA0xAgoodbye";
String two[] = one.split(" |0xA");
System.out.println(Arrays.toString(two));
Expected output: [hello, goodbye]
What I got: [hello, , , goodbye]
Why is this happening and how can I fix it?
Thanks in advance! ^-^
If you'd like to treat consecutive delimiters as one, you could modify your regex as follows:
"( |0xA)+"
This means "a space or the string "0xA", repeated one or more times".
(\\s|0xA)+ This will match one or more number of space or 0xA in the text and split them
This result is caused by multiple consecutive matches in the string. You may wrap the pattern with a grouping construct and apply a + quantifier to it to match multiple matches:
String one = "hello 0xA0xAgoodbye";
String two[] = one.split("(?:\\s|0xA)+");
System.out.println(Arrays.toString(two));
A (?:\s|0xA)+ regex matches 1 or more whitespace symbols or 0XA literal character sequences.
See the Java online demo.
However, you will still get an empty value as the first item in the resulting array if the 0xA or whitespaces appear at the start of the string. Then, you will have to remove them first:
String two[] = one.replaceFirst("^(?:\\s|0xA)+", "").split("(?:\\s+|0xA)+");
See another Java demo.

how to convert one line containing several sentences into lines according to dot(.) [duplicate]

I am wondering if I am going about splitting a string on a . the right way? My code is:
String[] fn = filename.split(".");
return fn[0];
I only need the first part of the string, that's why I return the first item. I ask because I noticed in the API that . means any character, so now I'm stuck.
split() accepts a regular expression, so you need to escape . to not consider it as a regex meta character. Here's an example :
String[] fn = filename.split("\\.");
return fn[0];
I see only solutions here but no full explanation of the problem so I decided to post this answer
Problem
You need to know few things about text.split(delim). split method:
accepts as argument regular expression (regex) which describes delimiter on which we want to split,
if delim exists at end of text like in a,b,c,, (where delimiter is ,) split at first will create array like ["a" "b" "c" "" ""] but since in most cases we don't really need these trailing empty strings it also removes them automatically for us. So it creates another array without these trailing empty strings and returns it.
You also need to know that dot . is special character in regex. It represents any character (except line separators but this can be changed with Pattern.DOTALL flag).
So for string like "abc" if we split on "." split method will
create array like ["" "" "" ""],
but since this array contains only empty strings and they all are trailing they will be removed (like shown in previous second point)
which means we will get as result empty array [] (with no elements, not even empty string), so we can't use fn[0] because there is no index 0.
Solution
To solve this problem you simply need to create regex which will represents dot. To do so we need to escape that .. There are few ways to do it, but simplest is probably by using \ (which in String needs to be written as "\\" because \ is also special there and requires another \ to be escaped).
So solution to your problem may look like
String[] fn = filename.split("\\.");
Bonus
You can also use other ways to escape that dot like
using character class split("[.]")
wrapping it in quote split("\\Q.\\E")
using proper Pattern instance with Pattern.LITERAL flag
or simply use split(Pattern.quote(".")) and let regex do escaping for you.
Split uses regular expressions, where '.' is a special character meaning anything. You need to escape it if you actually want it to match the '.' character:
String[] fn = filename.split("\\.");
(one '\' to escape the '.' in the regular expression, and the other to escape the first one in the Java string)
Also I wouldn't suggest returning fn[0] since if you have a file named something.blabla.txt, which is a valid name you won't be returning the actual file name. Instead I think it's better if you use:
int idx = filename.lastIndexOf('.');
return filename.subString(0, idx);
the String#split(String) method uses regular expressions.
In regular expressions, the "." character means "any character".
You can avoid this behavior by either escaping the "."
filename.split("\\.");
or telling the split method to split at at a character class:
filename.split("[.]");
Character classes are collections of characters. You could write
filename.split("[-.;ld7]");
and filename would be split at every "-", ".", ";", "l", "d" or "7". Inside character classes, the "." is not a special character ("metacharacter").
As DOT( . ) is considered as a special character and split method of String expects a regular expression you need to do like this -
String[] fn = filename.split("\\.");
return fn[0];
In java the special characters need to be escaped with a "\" but since "\" is also a special character in Java, you need to escape it again with another "\" !
String str="1.2.3";
String[] cats = str.split(Pattern.quote("."));
Wouldn't it be more efficient to use
filename.substring(0, filename.indexOf("."))
if you only want what's up to the first dot?
Usually its NOT a good idea to unmask it by hand. There is a method in the Pattern class for this task:
java.util.regex
static String quote(String s)
The split must be taking regex as a an argument... Simply change "." to "\\."
The solution that worked for me is the following
String[] fn = filename.split("[.]");
Note: Further care should be taken with this snippet, even after the dot is escaped!
If filename is just the string ".", then fn will still end up to be of 0 length and fn[0] will still throw an exception!
This is, because if the pattern matches at least once, then split will discard all trailing empty strings (thus also the one before the dot!) from the array, leaving an empty array to be returned.
Using ApacheCommons it's simplest:
File file = ...
FilenameUtils.getBaseName(file.getName());
Note, it also extracts a filename from full path.
split takes a regex as argument. So you should pass "\." instead of "." because "." is a metacharacter in regex.

how to ignore newlines for split function

I am splitting the string using ^ char. The String which I am reading, is coming from some external source. This string contains some \n characters.
The string may look like:
Hi hello^There\nhow are\nyou doing^9987678867abc^popup
when I am splitting like below, why the array length is coming as 2 instead of 4:
String[] st = msg[0].split("^");
st.length //giving "2" instead of "4"
It look like, split is ignoring after \n.
How can I fix it without replacing \n to some other character.
the string parameter for split is interpreted as regular expression.
So you have to escape the char and use:
st.split("\\^")
see this answer for more details
Escape the ^ character. Use msg[0].split("\\^") instead.
String.split considers its argument as regular expression. And as ^ has a special meaning when it comes to regular expressions, you need to escape it to use its literal representation.
If you want to split by ^ only, then
String[] st = msg[0].split("\\^");
If I read your question correctly, you want to split by ^ and \n characters, so this would suffice.
String[] st = msg[0].split("[\\^\\\\n]");
This considers that \n literally exists as 2 characters in a string.
"^" it's know as regular expression by the JDK.
To avoid this confusion you need to modify the code as below
old code = msg[0].split("^")
new code = msg[0].split("\\^")

Java Regex replaceAll() with lookahead

I am fairly new to using regex with java. My motive is to escape all occurrences of '*' with a back slash.
This was the statement that I tried:
String replacementStr= str.replaceAll("(?=\\[*])", "\\\\");
This does not seem to work though. After some amount of tinkering, found out that this works though.
String replacementStr= str.replaceAll("(?=[]\\[*])", "\\\\");
Based on what I know of regular expressions, I thought '[]' represents an empty character class. Am I missing something here? Can someone please help me understand this?
Note: The motive of my trial was to learn to use the lookahead feature of regex. While the purpose stated in the question does not warrant the use of lookahead, am just trying to use it for educational purposes. Sorry for not making that clear!
When some metacharacters are placed within brackets, no need to escape.
In another way, I do not know if you mean escape * with \*. In that case, try the next:
String newStr = str.replace("*", "\\*");
EDIT: There is something curious in your regular expressions.
(?=\[*]) Look ahead for the character [ (0 or more times), followed by ]
(?=[]\[*]) Look ahead for one of the next characters: [, ], *
Perhaps the regex that you are looking for is the following:
(?=\*)
In Java, "(?=\\*)"
In your replaceAll("(?=\\[*])", "\\\\"); simply modify as
String newStr = str.replace("*", "\\");
Dont bother about regex
For example
String str = "abc*123*";
String newStr = str.replace("*", "\\");
System.out.println(newStr);
Shows output as
abc\123\
Know about String replace
Below Code will work
Code
String strTest = "jhgfg*gfb*gfhh";
strTest = strTest.replaceAll("\\*", "\\\\"); // strTest = strTest.replace("*", "\\");
System.out.println("String is : "+strTest);
OUTPUT
String is : jhgfg\gfb\gfhh
If the regex engine finds [], it treats the ] as a literal ]. This is never a problem because an empty character class is useless anyway, and it means you can avoid some character escaping.
There are a few rules for characters you don't have to escape in character classes:
in [] (or [^]), the ] is literal
in [-.....] or [^-.....] or [.....-] or [^.....-], the - is literal
^ is literal unless it is at the start of the character class
So you'll never need to escape ], - or ^ if you don't want to.
This is down to the Perl origins of the regex syntax. It's a very Perl-style way of doing things.

Split string with dot as delimiter

I am wondering if I am going about splitting a string on a . the right way? My code is:
String[] fn = filename.split(".");
return fn[0];
I only need the first part of the string, that's why I return the first item. I ask because I noticed in the API that . means any character, so now I'm stuck.
split() accepts a regular expression, so you need to escape . to not consider it as a regex meta character. Here's an example :
String[] fn = filename.split("\\.");
return fn[0];
I see only solutions here but no full explanation of the problem so I decided to post this answer
Problem
You need to know few things about text.split(delim). split method:
accepts as argument regular expression (regex) which describes delimiter on which we want to split,
if delim exists at end of text like in a,b,c,, (where delimiter is ,) split at first will create array like ["a" "b" "c" "" ""] but since in most cases we don't really need these trailing empty strings it also removes them automatically for us. So it creates another array without these trailing empty strings and returns it.
You also need to know that dot . is special character in regex. It represents any character (except line separators but this can be changed with Pattern.DOTALL flag).
So for string like "abc" if we split on "." split method will
create array like ["" "" "" ""],
but since this array contains only empty strings and they all are trailing they will be removed (like shown in previous second point)
which means we will get as result empty array [] (with no elements, not even empty string), so we can't use fn[0] because there is no index 0.
Solution
To solve this problem you simply need to create regex which will represents dot. To do so we need to escape that .. There are few ways to do it, but simplest is probably by using \ (which in String needs to be written as "\\" because \ is also special there and requires another \ to be escaped).
So solution to your problem may look like
String[] fn = filename.split("\\.");
Bonus
You can also use other ways to escape that dot like
using character class split("[.]")
wrapping it in quote split("\\Q.\\E")
using proper Pattern instance with Pattern.LITERAL flag
or simply use split(Pattern.quote(".")) and let regex do escaping for you.
Split uses regular expressions, where '.' is a special character meaning anything. You need to escape it if you actually want it to match the '.' character:
String[] fn = filename.split("\\.");
(one '\' to escape the '.' in the regular expression, and the other to escape the first one in the Java string)
Also I wouldn't suggest returning fn[0] since if you have a file named something.blabla.txt, which is a valid name you won't be returning the actual file name. Instead I think it's better if you use:
int idx = filename.lastIndexOf('.');
return filename.subString(0, idx);
the String#split(String) method uses regular expressions.
In regular expressions, the "." character means "any character".
You can avoid this behavior by either escaping the "."
filename.split("\\.");
or telling the split method to split at at a character class:
filename.split("[.]");
Character classes are collections of characters. You could write
filename.split("[-.;ld7]");
and filename would be split at every "-", ".", ";", "l", "d" or "7". Inside character classes, the "." is not a special character ("metacharacter").
As DOT( . ) is considered as a special character and split method of String expects a regular expression you need to do like this -
String[] fn = filename.split("\\.");
return fn[0];
In java the special characters need to be escaped with a "\" but since "\" is also a special character in Java, you need to escape it again with another "\" !
String str="1.2.3";
String[] cats = str.split(Pattern.quote("."));
Wouldn't it be more efficient to use
filename.substring(0, filename.indexOf("."))
if you only want what's up to the first dot?
Usually its NOT a good idea to unmask it by hand. There is a method in the Pattern class for this task:
java.util.regex
static String quote(String s)
The split must be taking regex as a an argument... Simply change "." to "\\."
The solution that worked for me is the following
String[] fn = filename.split("[.]");
Note: Further care should be taken with this snippet, even after the dot is escaped!
If filename is just the string ".", then fn will still end up to be of 0 length and fn[0] will still throw an exception!
This is, because if the pattern matches at least once, then split will discard all trailing empty strings (thus also the one before the dot!) from the array, leaving an empty array to be returned.
Using ApacheCommons it's simplest:
File file = ...
FilenameUtils.getBaseName(file.getName());
Note, it also extracts a filename from full path.
split takes a regex as argument. So you should pass "\." instead of "." because "." is a metacharacter in regex.

Categories

Resources