I was trying to get an int (serial number of a student) from a string looks like "122. Fardinabir 170213" , where "122" is his serial number.
Before this, I tried using nextInt() method with a Scanner of the String, but nextInt() failed to do the job.
Then I have tried this procces...
import java.util.Scanner;
public class tempfile {
public static void main(String[] args) {
int serial_int = 0;
String serial_st;
serial_st = find_serial("122. FardinAbir 170213") ;
System.out.println(serial_st);
serial_int = Integer.parseInt(serial_st);
System.out.println(serial_int);
}
public static String find_serial(String st)
{
String[] parts = st.split(" "); // the first serial part will remain in parts[0]
parts[0].replaceAll("[\\D]", ""); // As I know it will remove non integer and the pure int serial will remain
return parts[0];
}
}
But, replaceAll("[\\D]", "") is not working...
Can anyone please help me to solve this or find a way out to this job...
Thanks in advance...
String line = "122. FardinAbir 170213";
Pattern pattern = Pattern.compile("^(\\d+)");
Matcher matcher = pattern.matcher(line);
if(matcher.find()) {
int id = Integer.parseInt(matcher.group(1));
System.out.println(id);
}
Assuming you also want to get the rest of the string eventually you can use Regex groups
String line = "122. FardinAbir 170213";
Pattern pattern = Pattern.compile("(\\d+)\\.\\s+([^\\s]+)\\s+(\\d+)");
Matcher matcher = pattern.matcher(line);
while (matcher.find()) {
System.out.println("serial: " + matcher.group(1));
int serial = Integer.parseInt(matcher.group(1));
System.out.println("group 2: " + matcher.group(2));
System.out.println("group 3: " + matcher.group(3));
}
nextInt() probably did not work because scanner expects newline separation
Since you tried using nextInt it seems you just want leading digits, which means you can use the following regex code:
public static String find_serial(String st) {
Matcher m = Pattern.compile("^\\d+").matcher(st);
return (m.find() ? m.group() : null);
}
You could also rely in the serial ending with a period, though that doesn't validate that serial is all digits:
public static String find_serial(String st) {
int idx = st.indexOf('.');
return (idx > 0 ? st.substring(0, idx) : null);
}
This'll do:
public static int getSerialNumber() {
String id = "122. Fardinabir 170213";
int place = 0;
for(int i = 0; i < id.length();i++) {
if(id.charAt(i) == '.') {
place = i;
break;
}
}
return Integer.parseInt(id.substring(0, place));
}
EDIT: you can also do it like this:
public static int getSerialNumber(String name) {
return Integer.parseInt(name.substring(0, name.indexOf('.')));
}
thanks #Andreas for that solution.
Related
In this code, we remove the substring "luna" from email string using the .replaceFirst method. We are removing the characters in between + and #. But this happens only in the first instance because we used .replaceFirst. What if we wanted to target the second instance of + and # to remove "smith"?
Our output now is alice+#john+smith#steve+oliver# but we want alice+luna#john+#steve+oliver#
public class Main {
public static void main(String[] args) {
String email = "alice+luna#john+smith#steve+oliver#";
String newEmail = email.replaceFirst("\\+.*?#", "");
System.out.println(newEmail);
}
}
You can find the second + like so:
int firstPlus = email.indexOf('+');
int secondPlus = email.indexOf('+', firstPlus + 1);
(You need to handle the case that there aren't two +s to find, if necessary).
Then find the following #:
int at = email.indexOf('#', secondPlus);
Then stitch it back together:
String newEmail = email.substring(0, secondPlus + 1) + email.substring(at);
or
String newEmail2 = new StringBuilder(email).delete(secondPlus + 1, at).toString();
Ideone demo
Unfortunately Java doesn't have methods like replace second, replace third etc. You can either replaceAll (which will replace all occurences) OR invoce replaceFirst again on the already replaced string. That's basically replacing the second. If you want to replace ONLY the second - then you can do it with substrings or do a regex matcher and iterate on results.
public static void main(String[] args) {
String email = "alice+luna#john+smith#steve+oliver#";
String newEmail = email.replaceFirst("\\+.*?#", "");
newEmail = newEmail .replaceFirst("\\+.*?#", ""); //this replaces the second right? :)
newEmail = newEmail .replaceFirst("\\+.*?#", ""); // replace 3rd etc.
System.out.println(newEmail);
}
You can alternate value of parameter n in following replaceNth method to 2, 3 to perform exactly the same operation as that of replaceSecond or replaceThird. ( Note: this method can be applied in any other value of n. If nth pattern do not exist , it simply return given string ).
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Main {
public static String replaceNth(String str, int n, String regex, String replaceWith) {
Pattern p = Pattern.compile(regex);
Matcher m = p.matcher(str);
while (m.find()) {
n--;
if (n == 0) {
return str.substring(0,m.start() + 1)+ replaceWith + str.substring(m.end() - 1);
}
}
return str;
}
public static void main(String args[]) {
String email = "alice+luna#john+smith#steve+oliver#";
System.out.println(replaceNth(email, 2, "\\+.*?#", ""));
}
}
I think it is better to encapsulate this logic into separate method, where String and group position are arguments.
private static final Pattern PATTERN = Pattern.compile("([^+#]+)#");
private static String removeSubstringGroup(String str, int pos) {
Matcher matcher = PATTERN.matcher(str);
while (matcher.find()) {
if (pos-- == 0)
return str.substring(0, matcher.start()) + str.substring(matcher.end() - 1);
}
return str;
}
Additionally, you can add more methods, to simplify using this util; like removeFirst() or removeLast()
public static String removeFirst(String str) {
return removeSubstringGroup(str, 0);
}
public static String removeSecond(String str) {
return removeSubstringGroup(str, 1);
}
Demo:
String email = "alice+luna#john+smith#steve+oliver#";
System.out.println(email);
System.out.println(removeFirst(email));
System.out.println(removeSecond(email));
System.out.println(removeSubstringGroup(email, 2));
System.out.println(removeSubstringGroup(email, 3));
Output:
alice+luna#john+smith#steve+oliver#
alice+#john+smith#steve+oliver#
alice+luna#john+#steve+oliver#
alice+luna#john+smith#steve+#
alice+luna#john+smith#steve+oliver#
Ideone demo
I have a requirement to replace all the character within a string to lower case if it is followed by some string like "is".
For example:
String a = "name=xyz,isSalaried=Y,address=abc,isManager=N,salary=1000";
it should get converted to
"name=xyz,salaried=Y,address=abc,manager=N,salary=1000"
I am not very good at regular expression but I think can use it to achieve the required output.
It will be great if someone can help me out.
Your solution requires basic understanding of String and String methods in java.
Here is one working example. Although, it might not be the most efficient one.
NOTE:- YOU ASKED FOR A REGEX SOLUTION.BUT THIS IS USING PURE STRING METHODS
public class CheckString{
public static void main(String[] ar){
String s = "name=xyz,isSalaried=Y,address=abc,isManager=N,salary=1000";
String[] arr = s.split(",");
String ans = "";
int i = 0;
for(String text : arr){
int index = text.indexOf("=");
String before = text.substring(0,index).replace("is","").toLowerCase();
String after = text.substring(index);
if(i!=(arr.length-1)){
ans += before + after + ",";
i++;
}
else{
ans += before + after;
}
}
System.out.println(ans);
}
}
Try this.
first match the string and replace in a loop
String a = "name=xyz,isSalaried=Y,address=abc,isManager=N,salary=1000";
Matcher matcher = Pattern.compile("is(.*?)=").matcher(a);//.matcher(a).replaceAll(m -> m.group(1).toLowerCase());
while (matcher.find()) {
String matchedString = matcher.group(1);
a = a.replace("is"+matchedString,matchedString.toLowerCase());
}
System.out.printf(a);
My task is splitting a string, which starts with numbers and contains numbers and letters, into two sub-strings.The first one consists of all numbers before the first letter. The second one is the remained part, and shouldn't be split even if it contains numbers.
For example, a string "123abc34de" should be split as: "123" and "abc34de".
I know how to write a regular expression for such a string, and it might look like this:
[0-9]{1,}[a-zA-Z]{1,}[a-zA-Z0-9]{0,}
I have tried multiple times but still don't know how to apply regex in String.split() method, and it seems very few online materials about this. Thanks for any help.
you can do it in this way
final String regex = "([0-9]{1,})([a-zA-Z]{1,}[a-zA-Z0-9]{0,})";
final String string = "123ahaha1234";
final Pattern pattern = Pattern.compile(regex);
final Matcher matcher = pattern.matcher(string);
while (matcher.find()) {
System.out.println("Full match: " + matcher.group(0));
for (int i = 1; i <= matcher.groupCount(); i++) {
System.out.println("Group " + i + ": " + matcher.group(i));
}
}
matcher.group(1) contains the first part and matcher.group(2) contains the second
you can add it to a list/array using these values
You can use a pretty simple pattern : "^(\\d+)(\\w+)" which capture digits as start, and then when letters appear it take word-char
String string = "123abc34de";
Matcher matcher = Pattern.compile("^(\\d+)(\\w+)").matcher(string);
String firstpart = "";
String secondPart = "";
if (matcher.find()) {
firstpart = matcher.group(1);
secondPart = matcher.group(2);
}
System.out.println(firstpart + " - " + secondPart); // 123 - abc34de
This is not the correct way but u will get the result
public static void main(String[] args) {
String example = "1234abc123";
int index = 0;
String[] arr = new String[example.length()];
for (int i = 0; i < example.length(); i++) {
arr = example.split("");
try{
if(Integer.parseInt(arr[i]) >= 0 & Integer.parseInt(arr[i]) <= 9){
index = i;
}
else
break;
}catch (NumberFormatException e) {
index = index;
}
}
String firstHalf = example.substring(0,Integer.parseInt(arr[index])+1);
String secondHalf = example.substring(Integer.parseInt(arr[index])+1,example.length());
System.out.println(firstHalf);
System.out.println(secondHalf);
}
Output will be: 1234 and in next line abc123
public class Md2html {
public static void main(String[] args) throws IOException {
String stringToConvert = new Scanner(System.in).nextLine();
System.out.println(convert(stringToConvert));
}
public static String convert(String str) {
if (str.equals("# "))
System.out.println(" ");
Pattern pattern = Pattern.compile("(#+[^#]+)");
Matcher matcher = pattern.matcher(str);
while (matcher.find()) {
String str1 = matcher.group(1);
if(str1.replaceFirst("#+", "").length() == 0 ||
str1.replaceFirst("#+", "").matches("[\\s]+"))
continue;
int n = str1.length() - str1.replaceFirst("#+", "").length();
System.out.println("<h" + n + ">" + str1.substring(n) +
"</h" + n + ">");
double carac;
carac = str.charAt(0);
if(carac>65 & carac <=90) {
System.out.print("<p>");
System.out.println(str);
System.out.println("<p>");
}
}
return ("");
}
}
Ok, so now I have an algorithm that converts # to < h1> < h2> depending on the number of #...I'm now trying to add < p> at the beginning of a paragraph and < /p> at the end of it. For some reason,the second part of the converter, which is supposed to add < p> at the beginning and < /p> at the end of a paragraph doesnt seem to work (it's the code starting with double carac). Can someone tell me what I'm doing wrong???
You are printing two opening tags for a paragraph if the string starts with an uppercase letter and no closing tag. Replace
System.out.print("<p>");
System.out.println(str);
System.out.println("<p>");
with
System.out.print("<p>");
System.out.println(str);
System.out.println("</p>"); //<--here
Also, you should use a logical AND && instead of a bitwise AND & for boolean operations.
Also, String#charAt(int) returns a char, not a double. You are declaring carac as a double. Declare as a char instead.
I have this String: "player.login name=username;x=52;y=406" how would I be able to split it so I easily could do Player pl = new Player(name, x, y) ?
I tried with a regex that looks like this: "([a-zA-Z_]+)[=]{1}([a-zA-Z0-9_]+)[;]{1}" but I'm not very good at regexs so it didn't work.
EDIT: Someone came up with a good solution so no need to comment. :)
What I used:
public static void main(String args[]) {
String login = "player.login name=username;x=52;y=406";
String str = login.substring("player.login".length() + 1);
String[] sp = str.split(";");
Player player = new Player("", 0, 0);
for (String s : sp) {
String[] a = s.split("=");
if (a[0].equals("name")) player.username = a[1];
else if (a[0].equals("x")) player.x = toInt(a[1]);
else if (a[0].equals("y")) player.y = toInt(a[1]);
}
System.out.println("Player: " + player.username + " # " + player.x + ", " + player.y);
}
public static int toInt(String s) {
return Integer.parseInt(s);
}
This should work (you should add bound checks before calling exp.split("=")[1]):
public static void main(String[] args) {
String s = "player.login name=username;x=52;y=406";
String[] expressions = s.split(";");
for (String exp : expressions) {
System.out.println(exp.split("=")[1]);
}
}
Since Java 7 there is support for named capturing groups, would be a nice usage here
String s = "player.login name=username;x=52;y=406";
Pattern p = Pattern.compile("name=(?<UserName>[^;]+);" + // Match the UserName in the Named Group "UserName", matching at least one non semicolon
"x=(?<x>\\d+);" + // Match the value of x in the Named Group "x", matching at least one digit
"y=(?<y>\\d+)" // Match the value of y in the Named Group "y", matching at least one digit
);
Matcher m = p.matcher(s);
if (m.find()) {
System.out.println(m.group("UserName"));
System.out.println(m.group("x"));
System.out.println(m.group("y"));
}
You could use String.split() three times, splitting on a space, then semicolon, then =. Or assylia's answer does it with two splits - best solution rather depends on whether you want to validate the parts of the text you are discarding.
Or using regex...
String regex = ".+=(\\w+);x=(\\d+);y=(\\d+)"
...which you can run with the following code:
Pattern p = Pattern.compile(".+=(\\w+);x=(\\d+);y=(\\d+)");
Matcher m = p.matcher("player.login name=username;x=52;y=406");
m.find();
System.out.println(m.group(1) + "," + m.group(2) + "," + m.group(3));
Or you can try with Guava:
String data = "player.login name=username;x=52;y=406";
List<String> fields = ImmutableList.copyOf(Splitter.on(' ').limit(2).split(data));
String type = fields.get(0);
Map<String, String> properties = Splitter.on(';').trimResults().withKeyValueSeparator("=").split(fields.get(1));
Try using a Pattern instead:
public static void main(String args[]){
String str = "player.login name=username;x=52;y=406";
Pattern p = Pattern.compile("^player\\.login name=(.+);x=(\\d+);y=(\\d+)$");
Matcher m = p.matcher(str);
Player player;
if (m.matches()){
String name = m.group(1);
int x = Integer.parseInt(m.group(2));
int y = Integer.parseInt(m.group(3));
System.out.println(name);
System.out.println(x);
System.out.println(y);
player = new Player(name, x, y);
} else {
player = null;
}
// Do stuff with player.
}