Suule
Suule

Reputation: 2478

How to find first character after second dot java

Do you have any ideas how could I get first character after second dot of the string.

String str1 = "test.1231.asdasd.cccc.2.a.2";
String str2 = "aaa.1.22224.sadsada";

In first case I should get a and in second 2. I thought about dividing string with dot, and extracting first character of third element. But it seems to complicated and I think there is better way.

Upvotes: 6

Views: 3458

Answers (7)

user2575725
user2575725

Reputation:

Just another approach, not a one-liner code but simple.

public class Test{
    public static void main (String[] args){
        for(String str:new String[]{"test.1231.asdasd.cccc.2.a.2","aaa.1.22224.sadsada"}){
            int n = 0;
            for(char c : str.toCharArray()){
                if(2 == n){
                    System.out.printf("found char: %c%n",c);
                    break;
                }
                if('.' == c){
                    n ++;   
                }
            }
        }
    }
}

found char: a
found char: 2

Upvotes: -1

LuCio
LuCio

Reputation: 5193

A plain solution using String.indexOf:

public static Character getCharAfterSecondDot(String s) {
    int indexOfFirstDot = s.indexOf('.');
    if (!isValidIndex(indexOfFirstDot, s)) {
        return null;
    }

    int indexOfSecondDot = s.indexOf('.', indexOfFirstDot + 1);
    return isValidIndex(indexOfSecondDot, s) ?
            s.charAt(indexOfSecondDot + 1) :
            null;
}

protected static boolean isValidIndex(int index, String s) {
    return index != -1 && index < s.length() - 1;
}

Using indexOf(int ch) and indexOf(int ch, int fromIndex) needs only to examine all characters in worst case.

And a second version implementing the same logic using indexOf with Optional:

public static Character getCharAfterSecondDot(String s) {
    return Optional.of(s.indexOf('.'))
            .filter(i -> isValidIndex(i, s))
            .map(i -> s.indexOf('.', i + 1))
            .filter(i -> isValidIndex(i, s))
            .map(i -> s.charAt(i + 1))
            .orElse(null);
}

Upvotes: 0

Ashishkumar Singh
Ashishkumar Singh

Reputation: 3600

Without using pattern, you can use subString and charAt method of String class to achieve this

// You can return String instead of char
public static char returnSecondChar(String strParam) {
    String tmpSubString = "";
   // First check if . exists in the string.
    if (strParam.indexOf('.') != -1) {
        // If yes, then extract substring starting from .+1  
        tmpSubString = strParam.substring(strParam.indexOf('.') + 1);
        System.out.println(tmpSubString);

       // Check if second '.' exists
        if (tmpSubString.indexOf('.') != -1) {

            // If it exists, get the char at index of . + 1  
            return tmpSubString.charAt(tmpSubString.indexOf('.') + 1);
        }
    }
    // If 2 '.' don't exists in the string, return '-'. Here you can return any thing
    return '-';
}

Upvotes: 2

dbl
dbl

Reputation: 1109

Usually regex will do an excellent work here. Still if you are looking for something more customizable then consider the following implementation:

private static int positionOf(String source, String target, int match) {
    if (match < 1) {
        return -1;
    }
    int result = -1;

    do {
        result = source.indexOf(target, result + target.length());
    } while (--match > 0 && result > 0);

    return result;
}

and then the test is done with:

String str1 = "test..1231.asdasd.cccc..2.a.2.";

System.out.println(positionOf(str1, ".", 3)); -> // prints 10
System.out.println(positionOf(str1, "c", 4)); -> // prints 21
System.out.println(positionOf(str1, "c", 5)); -> // prints -1
System.out.println(positionOf(str1, "..", 2)); -> // prints 22 -> just have in mind that the first symbol after the match is at position 22 + target.length() and also there might be none element with such index in the char array.

Upvotes: 2

Nikolas
Nikolas

Reputation: 44506

You can use Java Stream API since Java 8:

String string = "test.1231.asdasd.cccc.2.a.2";
Arrays.stream(string.split("\\."))                 // Split by dot
      .skip(2).limit(1)                            // Skip 2 initial parts and limit to one
      .map(i -> i.substring(0, 1))                 // Map to the first character
      .findFirst().ifPresent(System.out::println); // Get first and print if exists

However, I recommend you to stick with Regex, which is safer and a correct way to do so:


Here is the Regex you need (demo available at Regex101):

.*?\..*?\.(.).*

Don't forget to escape the special characters with double-slash \\.

String[] array = new String[3];
array[0] = "test.1231.asdasd.cccc.2.a.2";
array[1] = "aaa.1.22224.sadsada";
array[2] = "test";

Pattern p = Pattern.compile(".*?\\..*?\\.(.).*");
for (int i=0; i<array.length; i++) {
    Matcher m = p.matcher(array[i]);
    if (m.find()) {
         System.out.println(m.group(1));
    }
}

This code prints two results on each line: a, 2 and an empty lane because on the 3rd String, there is no match.

Upvotes: 1

deHaar
deHaar

Reputation: 18588

You could do it by splitting the String like this:

public static void main(String[] args) {
    String str1 = "test.1231.asdasd.cccc.2.a.2";
    String str2 = "aaa.1.22224.sadsada";

    System.out.println(getCharAfterSecondDot(str1));
    System.out.println(getCharAfterSecondDot(str2));
}

public static char getCharAfterSecondDot(String s) {
    String[] split = s.split("\\.");
    // TODO check if there are values in the array!
    return split[2].charAt(0);
}

I don't think it is too complicated, but using a directly matching regex is a very good (maybe better) solution anyway.

Please note that there might be the case of a String input with less than two dots, which would have to be handled (see TODO comment in the code).

Upvotes: 1

Eugene
Eugene

Reputation: 121088

How about a regex for this?

Pattern p = Pattern.compile(".+?\\..+?\\.(\\w)");
Matcher m = p.matcher(str1);

if (m.find()) {
     System.out.println(m.group(1));
}

The regex says: find anything one or more times in a non-greedy fashion (.+?), that must be followed by a dot (\\.), than again anything one or more times in a non-greedy fashion (.+?) followed by a dot (\\.). After this was matched take the first word character in the first group ((\\w)).

Upvotes: 10

Related Questions