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.
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
I'm assuming you did something like:
String[] parts = str.split("^");
That doesn't work because the argument to split is actually a regular expression, where ^ has a special meaning. Try this instead:
String[] parts = str.split("\\^");
The \\ is really equivalent to a single \ (the first \ is required as a Java escape sequence in string literals). It is then a special character in regular expressions which means "use the next character literally, don't interpret its special meaning".
The regex you should use is "\^" which you write as "\\^" as a Java String literal; i.e.
String[] parts = "Good^Evening".split("\\^");
The regex needs a '\' escape because the caret character ('^') is a meta-character in the regex language. The 2nd '\' escape is needed because '\' is an escape in a String literal.
Using split("\\|") is the same as split("\\|", 0), where the limit parameter 0 tells the function "omit trailing empty strings". So you are missing the last two empty strings. Use the two-argument version and supply a negative number to obtain all parts (even trailing empty ones):
str.split("\\|", -1)
Print:
System.out.println(Arrays.toString(str.split("\\|")));
And you'll understand why it's printing 6.
You can try doing what you want using public String[] split(String regex, int limit):
The limit parameter controls the number of times the pattern is applied and therefore affects the length of the resulting array.
So you should do:
System.out.println(str.split("\\|", -1).length);
Now, printing the array will print:
[, , 81, , , 01, , ] as you expected.
try this:
String[] cs = s.split("");
I'm curious why you want to do this. Strings can be read basically as arrays with charAt(). You can turn a string into a stream with StringReader. You can turn a string into an IntStream with chars() or codePoints(). Or you can just get a copy if its internal character array with toCharArray().
Regarding something you said in the comments about toCharArray() or .split() cutting off, they don't. You must have a bug somewhere, please show us your code.
public static void main( String[] args ) {
String test = "Hello! My name is x";
char[] chars = test.toCharArray();
System.out.println( Arrays.toString( chars ) );
}
This prints the whole string for me and doesn't cut off.
run:
[H, e, l, l, o, !, , M, y, , n, a, m, e, , i, s, , x]
BUILD SUCCESSFUL (total time: 0 seconds)
Update: Regarding your update, next() finds tokens, which by default are cut off at white space. You want nextLine().
return Arrays.asList(scanner.next().split(""));
Change to:
return Arrays.asList(scanner.nextLine().split(""));
Try to use Pattern.quote to avoid escaping character by character, It will do that free for you :
String[] suburl = mySuburl.split(Pattern.quote("-{name-of-perpetrators"));
The argument for split is a regex. So, you need to escape the special characters used in regex like {. {} is used to denote repetition in regex and hence the error Illegal repetition.
String[] suburl = mySuburl.split("-\\{name-of-perpetrators");
If you don't want the argument for split to be a regex, use Pattern.quote to avoid escaping as @YCF_L suggested.
String[] suburl = mySuburl.split(Pattern.quote("-{name-of-perpetrators"));
The split() method on String takes a RegEx. What you are passing is an invalid RegEx. You are better off using the substring() function as you already know the prefix and suffix pattern.
test = test.substring(patternOne.length(), test.length() - patternTwo.length());
shouldn't this be the easier way ? since you are overriding your test variable anyways you could just replace your patterns with nothing. and you would not need to check if test contains them at all
String test = "^((?!PATT).)*$";
String patternOne = "^((?!";
String patternTwo = ").)*$";
test = test.replace(patternOne, "").replace(patternTwo,"");
Use the appropriately named method String#split().
String string = "004-034556";
String[] parts = string.split("-");
String part1 = parts[0]; // 004
String part2 = parts[1]; // 034556
Note that split's argument is assumed to be a regular expression, so remember to escape special characters if necessary.
there are 12 characters with special meanings: the backslash
\, the caret^, the dollar sign$, the period or dot., the vertical bar or pipe symbol|, the question mark?, the asterisk or star*, the plus sign+, the opening parenthesis(, the closing parenthesis), and the opening square bracket[, the opening curly brace{, These special characters are often called "metacharacters".
For instance, to split on a period/dot . (which means "any character" in regex), use either backslash \ to escape the individual special character like so split("\\."), or use character class [] to represent literal character(s) like so split("[.]"), or use Pattern#quote() to escape the entire string like so split(Pattern.quote(".")).
String[] parts = string.split(Pattern.quote(".")); // Split on the exact string.
To test beforehand if the string contains certain character(s), just use String#contains().
if (string.contains("-")) {
// Split it.
} else {
throw new IllegalArgumentException("String " + string + " does not contain -");
}
Note, this does not take a regular expression. For that, use String#matches() instead.
If you'd like to retain the split character in the resulting parts, then make use of positive lookaround. In case you want to have the split character to end up in left hand side, use positive lookbehind by prefixing ?<= group on the pattern.
String string = "004-034556";
String[] parts = string.split("(?<=-)");
String part1 = parts[0]; // 004-
String part2 = parts[1]; // 034556
In case you want to have the split character to end up in right hand side, use positive lookahead by prefixing ?= group on the pattern.
String string = "004-034556";
String[] parts = string.split("(?=-)");
String part1 = parts[0]; // 004
String part2 = parts[1]; // -034556
If you'd like to limit the number of resulting parts, then you can supply the desired number as 2nd argument of split() method.
String string = "004-034556-42";
String[] parts = string.split("-", 2);
String part1 = parts[0]; // 004
String part2 = parts[1]; // 034556-42
An alternative to processing the string directly would be to use a regular expression with capturing groups. This has the advantage that it makes it straightforward to imply more sophisticated constraints on the input. For example, the following splits the string into two parts, and ensures that both consist only of digits:
import java.util.regex.Pattern;
import java.util.regex.Matcher;
class SplitExample
{
private static Pattern twopart = Pattern.compile("(\\d+)-(\\d+)");
public static void checkString(String s)
{
Matcher m = twopart.matcher(s);
if (m.matches()) {
System.out.println(s + " matches; first part is " + m.group(1) +
", second part is " + m.group(2) + ".");
} else {
System.out.println(s + " does not match.");
}
}
public static void main(String[] args) {
checkString("123-4567");
checkString("foo-bar");
checkString("123-");
checkString("-4567");
checkString("123-4567-890");
}
}
As the pattern is fixed in this instance, it can be compiled in advance and stored as a static member (initialised at class load time in the example). The regular expression is:
(\d+)-(\d+)
The parentheses denote the capturing groups; the string that matched that part of the regexp can be accessed by the Match.group() method, as shown. The \d matches and single decimal digit, and the + means "match one or more of the previous expression). The - has no special meaning, so just matches that character in the input. Note that you need to double-escape the backslashes when writing this as a Java string. Some other examples:
([A-Z]+)-([A-Z]+) // Each part consists of only capital letters
([^-]+)-([^-]+) // Each part consists of characters other than -
([A-Z]{2})-(\d+) // The first part is exactly two capital letters,
// the second consists of digits