【问题标题】:How to find first character after second dot java如何在第二个点java之后找到第一个字符
【发布时间】:2019-01-30 20:34:43
【问题描述】:

你有什么想法我怎样才能在字符串的第二个点之后获得第一个字符。

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

在第一种情况下我应该得到a,在第二种情况下我应该得到2。 我想过用点分割字符串,并提取第三个元素的第一个字符。但这似乎很复杂,我认为有更好的方法。

【问题讨论】:

  • 到目前为止你有没有尝试过?
  • 你试过正则表达式吗?这当然不那么复杂:)
  • 亚瑟,正如我之前写的,分裂。但是好像不行。

标签: java regex string java-8


【解决方案1】:

这个正则表达式怎么样?

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

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

正则表达式说:以非贪婪的方式找到任何东西一次或多次(.+?),后面必须跟一个点(\\.),而不是再次以非贪婪的方式找到一次或多次时尚 (.+?) 后跟一个点 (\\.)。匹配后,取第一组中的第一个单词字符 ((\\w))。

【讨论】:

  • 你能解释一下正则表达式吗?
  • OP 没有强制要求的字符是单词字符,所以你应该只使用. 而不是\w。你可以避免重复自己:Pattern p = Pattern.compile("(?:.+?\\.){2}(.)");。如果要在不经过String 的情况下提取char,也可以使用Matcher m = p.matcher(str1); if(m.find()) { char c = str1.charAt(m.start(1)); }。或者,如果你想要一个字符串,你可以临时做:String s = str1.replaceFirst("(?:.+?\\.){2}(.).*", "$1");
  • .+? -> .*? 没有地方说点之间应该有字符
  • @loa_in_ 你可能是对的,我只是拿了问题中的 OP 示例
【解决方案2】:

通常正则表达式会在这里做得很好。不过,如果您正在寻找更可定制的东西,那么请考虑以下实现:

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;
}

然后测试完成:

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

System.out.println(positionOf(str1, ".", 3)); -> // 打印 10
System.out.println(positionOf(str1, "c", 4)); -> // 打印 21
System.out.println(positionOf(str1, "c", 5)); -> // 打印 -1
System.out.println(positionOf(str1, "..", 2)); -> // 打印 22 -> 请记住,匹配后的第一个符号位于 22 + target.length() 位置,并且在 char 数组中可能没有具有此类索引的元素。

【讨论】:

    【解决方案3】:

    不使用模式,可以使用String类的subStringcharAt方法来实现

    // 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 '-';
    }
    

    【讨论】:

    • 不需要使用 subString,因为 indexOf 提供了采用起始索引的实现。
    • 我打电话给substring,因为我想检查一下。存在的不存在。如果是,则再次致电indexof
    【解决方案4】:

    您可以像这样拆分String 来做到这一点:

    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);
    }
    

    我不认为它太复杂,但无论如何使用直接匹配的正则表达式是一个非常好的(也许更好)的解决方案。

    请注意,String 输入可能会出现少于两个点的情况,这是必须处理的(参见代码中的 TODO 注释)。

    【讨论】:

      【解决方案5】:

      您可以从 Java 8 开始使用 Java Stream API:

      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
      

      但是,我建议您坚持使用 Regex,这是更安全且正确的方法:


      这是您需要的正则表达式(可在Regex101 获得演示):

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

      别忘了用双斜线 \\ 转义特殊字符。

      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));
          }
      }
      

      此代码在每一行打印两个结果:a2 和一个空通道,因为在第三个字符串上,没有匹配项。

      【讨论】:

      • 使用string.split("\\.", 3) 会使limit(1) 过时。由于流最多有一个元素,因此您可以使用forEach(…) 而不是.findFirst().ifPresent(…)。在正则表达式中,末尾的 .* 已过时。
      【解决方案6】:

      使用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;
      }
      

      使用indexOf(int ch)indexOf(int ch, int fromIndex) 只需要在最坏的情况下检查所有字符。

      第二个版本使用 indexOfOptional 实现相同的逻辑:

      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);
      }
      

      【讨论】:

        【解决方案7】:

        只是另一种方法,不是单行代码,而是简单。

        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 ++;   
                        }
                    }
                }
            }
        }
        

        找到字符:a
        找到字符:2

        【讨论】:

        • 问题被标记为 [java] :)
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-07-19
        • 1970-01-01
        • 1970-01-01
        • 2021-10-21
        相关资源
        最近更新 更多