Extracting 5 characters from string - java

I am a newbie to Java and struggling with a possibly simple thing.
I have strings in different formats. An example string is given below
New_System-Updater-For-19974774.ftw
Basically i want to extract the number "19974774". For this i want to find the index where "." is, as there will be only dot in the string and then go back and extract the 8 characters.
Is there a simple way of doing it?

String s = "New_System-Updater-For-19974774.ftw";
int positionOfDot = s.indexOf('.');
String withoutDotFtw = s.substring(0,positionOfDot);
String number = s.substring(s.lastIndexOf("-")+1,positionOfDot);
You can try something like this

If you want 8 char before dot i suggest :
String tst = "New_System-Updater-For-19974774.ftw";
int indexOfDot = tst.indexOf(".");
String extract = tst.substring(indexOfDot-8, indexOfDot);
System.out.println(extract);
If size of digit it not 8 digit, use regex
Pattern pattern = Pattern.compile("(\\d+)\\.");
Matcher matcher = pattern.matcher(tst);
if(matcher.find()){
extract = matcher.group(1);
}
System.out.println(extract);

Try something like this:
public static string GetNumberFromName(String name) {
String myString = "New_System-Updater-For-19974774.ftw";
return myString.split("\\d+\\.")[0].split("\\d+")[0];
}

You can use the following code to retrieve the numbers you want.
Pattern pattern = Pattern.compile("\\D*(\\d*)\\D*");
Matcher matcher = pattern.matcher(s);
if (matcher.find()) {
System.out.println(matcher.group(1));
}

Assuming there is always a - before the digits this will work:
String initial = "New_System-Updater-For-19974774.ftw";
String firstSplit = initial.substring(initial.lastIndexOf("-") + 1);
String finalSplit = firstSplit.substring(0, firstSplit.indexOf("."));
Assuming the number of digits are fixed to 8, this will work:
String initial = "New_System-Updater-For-19974774.ftw";
String firstSplit = initial.substring(0, initial.lastIndexOf("."));
String finalSplit = firstSplit.substring(firstSplit.length()-8, firstSplit.length());
finalSplit will be your number.

Making the assumption that you want the number in front of the last period in your string. You should use a regex ideally, but this may be simpler if regex is unfamiliar.
String string = New_System-Updater-For-19974774.ftw";
String[] splitString = string.split('.');
if(splitString.length > 1) {
String secondToLastString = splitString[splitString.length - 2]; //second to last string
int i = secondToLastString.length - 1;
for(; i >= 0; i--) {
if(!Character.isDigit(secondToLastString.charAt(i))) {//If not digit break out and use that index as bound
break;
}
}
return secondToLastString.substring(i + 1);
} else {
throw new IllegalArgumentException("string doesn't have proper format");
}
Or just use a regex
String string = New_System-Updater-For-19974774.ftw";
Matcher matcher = Pattern.compile("(\\d*)\\.[^\\.]*").matcher(string);
if(matcher.find()) {
return matcher.group(1);
}

Related

How can I grep same format substrings within a long string by java regular expression?

For example, I want to grep both /css/screen/shared/styles.css and /css/screen/nol/styles.css from this long string:
#import "/css/screen/shared/styles.css";
#import "/css/screen/nol/styles.css";
Note that this long string contains 2 lines, it should look like this in java code:
String sentence = "#import \"/css/screen/nol/styles.css\";\n#import \"/css/screen/shared/styles.css\";";
So far, I have:
"#import\\s\"(.*?)\";\n"
it only identifies the "/css/screen/shared/styles.css", but ignores the "/css/screen/nol/styles.css".
Here is my code:
public static String getImportCSS(String sentence){
String result = "";
if(sentence.length() == 0) return null;
if(sentence.indexOf("#import ") != -1){
Pattern regex = Pattern.compile("#import\\s\"(.*)\";");
Matcher regexMatcher = regex.matcher(sentence);
if(regexMatcher.find()){
for(int i = 0; i <= regexMatcher.groupCount(); i++){
result = regexMatcher.group(1);
}
}
return result;
}
return null;
}
What am I doing wrong here? Thanks!
You cannot match the second string because your regex has an LF (\n) at the end.
Remove it, and the pattern will find both the strings. However, I'd advise to use a negated character class [^"]* (zero or more characters other than a ") rather than a lazy dot matching since the strings should not contain a double quote:
#import\s*\"([^"]*)\";
See the regex demo
Java demo:
String str = "#import \"/css/screen/shared/styles.css\";\n#import \"/css/screen/nol/styles.css\";";
Pattern ptrn = Pattern.compile("#import\\s*\"([^\"]*)\";");
Matcher matcher = ptrn.matcher(str);
while (matcher.find()) {
System.out.println(matcher.group(1));
}

How to replace all {!XXX} from string?

I have string with multiple {!XXX} phrases. For example:
Kumar gaurav {!str1} is just {!str2}, adasdas {!str3}
I need to replace all {!str} values with corresponding str, how to replace all {!str} from my string?
You can use a Pattern and Matcher, which provides you the means to query the string for a unknown number of elements, in combination with a regular expression of \{!str\d\} which will allow you to break the text down based on the tags
For example...
String text = "All that {!str1} is {!str2}";
Map<String, String> values = new HashMap<>(25);
values.put("{!str1}", "glitters");
values.put("{!str2}", "gold");
Pattern p = Pattern.compile("\\{!str\\d\\}");
Matcher matcher = p.matcher(text);
while (matcher.find()) {
String match = matcher.group();
text = text.replaceAll("\\" + match, values.get(match));
}
System.out.println(text);
Which outputs
All that glitters is gold
You could also use something like...
int previousStart = 0;
StringBuilder sb = new StringBuilder();
while (matcher.find()) {
String match = matcher.group();
int start = matcher.start();
int end = matcher.end();
sb.append(text.substring(previousStart, start));
sb.append(values.get(match));
previousStart = end;
}
if (previousStart < text.length()) {
sb.append(text.substring(previousStart));
}
Which does away with the String creation in a loop and relies more on the position of the match to cut the original text around the tokens, which makes me happier ;)
use this regex, simple
String string="hello world {!hello}";
string=string.replaceAll("\\{!(.*?)\\}", "replace");
System.out.println(string); //this will print (hello world replace)

How to return the first chunk of either numerics or letters from a string?

For example, if I had (-> means return):
aBc123afa5 -> aBc
168dgFF9g -> 168
1GGGGG -> 1
How can I do this in Java? I assume it's something regex related but I'm not great with regex and so not too sure how to implement it (I could with some thought but I have a feeling it would be 5-10 lines long, and I think this could be done in a one-liner).
Thanks
String myString = "aBc123afa5";
String extracted = myString.replaceAll("^([A-Za-z]+|\\d+).*$", "$1");
View the regex demo and the live code demonstration!
To use Matcher.group() and reuse a Pattern for efficiency:
// Class
private static final Pattern pattern = Pattern.compile("^([A-Za-z]+|\\d+).*$");
// Your method
{
String myString = "aBc123afa5";
Matcher matcher = pattern.matcher(myString);
if(matcher.matches())
System.out.println(matcher.group(1));
}
Note: /^([A-Za-z]+|\d+).*$ and /^([A-Za-z]+|\d+)/ both works in similar efficiency. On regex101 you can compare the matcher debug logs to find out this.
Without using regex, you can do this:
String string = "168dgFF9g";
String chunk = "" + string.charAt(0);
boolean searchDigit = Character.isDigit(string.charAt(0));
for (int i = 1; i < string.length(); i++) {
boolean isDigit = Character.isDigit(string.charAt(i));
if (isDigit == searchDigit) {
chunk += string.charAt(i);
} else {
break;
}
}
System.out.println(chunk);
public static String prefix(String s) {
return s.replaceFirst("^(\\d+|\\pL+|).*$", "$1");
}
where
\\d = digit
\\pL = letter
postfix + = one or more
| = or
^ = begin of string
$ = end of string
$1 = first group `( ... )`
An empty alternative (last |) ensures that (...) is always matched, and always a replace happens. Otherwise the original string would be returned.

Extract every complete word that contains a certain substring

I'm trying to write a function that extracts each word from a sentence that contains a certain substring e.g. Looking for 'Po' in 'Porky Pork Chop' will return Porky Pork.
I've tested my regex on regexpal but the Java code doesn't seem to work. What am I doing wrong?
private static String foo()
{
String searchTerm = "Pizza";
String text = "Cheese Pizza";
String sPattern = "(?i)\b("+searchTerm+"(.+?)?)\b";
Pattern pattern = Pattern.compile ( sPattern );
Matcher matcher = pattern.matcher ( text );
if(matcher.find ())
{
String result = "-";
for(int i=0;i < matcher.groupCount ();i++)
{
result+= matcher.group ( i ) + " ";
}
return result.trim ();
}else
{
System.out.println("No Luck");
}
}
In Java to pass \b word boundaries to regex engine you need to write it as \\b. \b represents backspace in String object.
Judging by your example you want to return all words that contains your substring. To do this don't use for(int i=0;i < matcher.groupCount ();i++) but while(matcher.find()) since group count will iterate over all groups in single match, not over all matches.
In case your string can contain some special characters you probably should use Pattern.quote(searchTerm)
In your code you are trying to find "Pizza" in "Cheese Pizza" so I assume that you also want to find strings that same as searched substring. Although your regex will work fine for it, you can change your last part (.+?)?) to \\w* and also add \\w* at start if substring should also be matched in the middle of word (not only at start).
So your code can look like
private static String foo() {
String searchTerm = "Pizza";
String text = "Cheese Pizza, Other Pizzas";
String sPattern = "(?i)\\b\\w*" + Pattern.quote(searchTerm) + "\\w*\\b";
StringBuilder result = new StringBuilder("-").append(searchTerm).append(": ");
Pattern pattern = Pattern.compile(sPattern);
Matcher matcher = pattern.matcher(text);
while (matcher.find()) {
result.append(matcher.group()).append(' ');
}
return result.toString().trim();
}
While the regex approach is certainly a valid method, I find it easier to think through when you split the words up by whitespace. This can be done with String's split method.
public List<String> doIt(final String inputString, final String term) {
final List<String> output = new ArrayList<String>();
final String[] parts = input.split("\\s+");
for(final String part : parts) {
if(part.indexOf(term) > 0) {
output.add(part);
}
}
return output;
}
Of course it is worth nothing that doing this will effectively be doing two passes through your input String. The first pass to find the characters that are whitespace to split on, and the second pass looking through each split word for your substring.
If one pass is necessary though, the regex path is better.
I find nicholas.hauschild's answer to be the best.
However if you really wanted to use regex, you could do it as such:
String searchTerm = "Pizza";
String text = "Cheese Pizza";
Pattern pattern = Pattern.compile("\\b" + Pattern.quote(searchTerm)
+ "\\b", Pattern.CASE_INSENSITIVE);
Matcher matcher = pattern.matcher(text);
while (matcher.find()) {
System.out.println(matcher.group());
}
Output:
Pizza
The pattern should have been
String sPattern = "(?i)\\b("+searchTerm+"(?:.+?)?)\\b";
You want to capture the whole (pizza)string.?: ensures you don't capture a part of the string twice.
Try this pattern:
String searchTerm = "Po";
String text = "Porky Pork Chop oPod zzz llPo";
Pattern p = Pattern.compile("\\p{Alpha}+" + substring + "|\\p{Alpha}+" + substring + "\\p{Alpha}+|" + substring + "\\p{Alpha}+");
Matcher m = p.matcher(myString);
while(m.find()) {
System.out.println(">> " + m.group());
}
Ok, I give you a pattern in raw style (not java style, you must double escape yourself):
(?i)\b[a-z]*po[a-z]*\b
And that's all.

How to remove the commas from numeric string result?

I have result, which is either a text or numeric value, such as:
String result;
result = "avsds";
result = "123";
result = "345.45";
Sometimes the results also contain commas like:
result = "abc,def";
result = "1,234";
I want to remove the commas from result only if it is a numeric value, and not if it is simple text.
What is the best way of going about this?
Here is your answer:
String regex = "(?<=[\\d])(,)(?=[\\d])";
Pattern p = Pattern.compile(regex);
String str = "Your input";
Matcher m = p.matcher(str);
str = m.replaceAll("");
System.out.println(str);
This only affects NUMBERS, not strings, as you asked.
Try adding that in your main method. Or try this one, it receives input:
String regex = "(?<=[\\d])(,)(?=[\\d])";
Pattern p = Pattern.compile(regex);
System.out.println("Value?: ");
Scanner scanIn = new Scanner(System.in);
String str = scanIn.next();
Matcher m = p.matcher(str);
str = m.replaceAll("");
System.out.println(str);
The easiest way is to use two regexes. The first to make sure it is numeric (something along the lines of [0-9.,]*), and the second to clean it (result.replaceAll("/,//"))
You could try to parse the string first with any of the numeric classes (Integer, Double etc) after removing the unwanted characters, if the parsing succeeds, then it is a numeric and you can remove the unwanted characters from the original string.
Here I have used BigInteger since I am not sure about the precision for your requirement.
public static String removeIfNumeric(final String s, final String toRemove) {
final String result;
if (isNumeric(s, toRemove)) {
result = s.replaceAll(toRemove, "");
} else {
result = s;
}
return result;
}
public static boolean isNumeric(final String s, final String toRemoveRegex) {
try {
new BigInteger(s.replaceAll(toRemoveRegex, ""));
return true;
} catch (NumberFormatException e) {
return false;
}
}

Categories