121

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.

c0der
  • 18,467
  • 6
  • 33
  • 65
Dean
  • 8,668
  • 17
  • 57
  • 86

13 Answers13

199

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];
Unmitigated
  • 76,500
  • 11
  • 62
  • 80
Marimuthu Madasamy
  • 13,126
  • 4
  • 30
  • 52
  • In this case, you must use two backslashes. Apparantly, the `split()` method requires the use of two backslashes due to the fact that it is a method that interprets a String type, which in itself refers to a literal dot. [reference: Pshemo's solution] – Ron Zhang May 28 '22 at 00:48
24

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:

  1. accepts as argument regular expression (regex) which describes delimiter on which we want to split,
  2. 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

  1. create array like ["" "" "" ""],
  2. 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.
Pshemo
  • 122,468
  • 25
  • 185
  • 269
17

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);
Andrei Fierbinteanu
  • 7,656
  • 3
  • 31
  • 45
15

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").

f1sh
  • 11,489
  • 3
  • 25
  • 51
  • @MisterSmith You might want to take a look at the programming language here. We're talking about java, not javascript. – f1sh Nov 28 '13 at 08:40
  • You are absolutely right. I was tired yesterday, having being coding in both languages, didn't notice the Java datatypes. I thought perhaps the answers were correct back in 2010 but somehow the browsers today behaved in a different manner. – Mister Smith Nov 28 '13 at 09:12
7

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 "\" !

Neel
  • 429
  • 7
  • 17
5
String str="1.2.3";
String[] cats = str.split(Pattern.quote("."));
SHR
  • 7,940
  • 9
  • 38
  • 57
Magnus Persson
  • 101
  • 2
  • 4
3

Wouldn't it be more efficient to use

 filename.substring(0, filename.indexOf("."))

if you only want what's up to the first dot?

Martin Smith
  • 438,706
  • 87
  • 741
  • 845
2

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) 
Christian Ullenboom
  • 1,388
  • 3
  • 24
  • 20
2

The solution that worked for me is the following

String[] fn = filename.split("[.]");
Sundar R
  • 13,776
  • 6
  • 49
  • 76
Jorge Santos
  • 397
  • 4
  • 3
1

The split must be taking regex as a an argument... Simply change "." to "\\."

Bob Fincheimer
  • 17,978
  • 1
  • 29
  • 54
0

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.

avl42
  • 11
  • 1
  • easiest solution in cases like the one at hand is to also pass a limit-argument of 2 to the call to split: String[] fn = filename.split("[.]",2); – avl42 Jul 27 '18 at 07:55
0

Using ApacheCommons it's simplest:

File file = ...
FilenameUtils.getBaseName(file.getName());

Note, it also extracts a filename from full path.

-3

split takes a regex as argument. So you should pass "\." instead of "." because "." is a metacharacter in regex.

pushkin
  • 9,575
  • 15
  • 51
  • 95
Vijay Mathew
  • 26,737
  • 4
  • 62
  • 93