2017-09-29 46 views
-1

我想從字符串中獲取第一個數字出現的第一個字符(非數字)。字符串可以是任何字符,也可以包含數字。我只需要關心前兩個索引。有點棘手的部分是讓第二個索引包含一個數字,然後只有第一個字符需要考慮。有沒有一個優雅的方式來從字符串中獲取兩個連續字符,直到出現第一個數字

Examples: 

abcd -> ab 
a -> a 
a0cd -> a 
0bcd -> null 
-123 -> null 

下面是我如何在java中編寫這個函數。有沒有其他優雅的方式來做到這一點?任何幫助深表感謝。

public class Main { 
    public static String getFirstTwoCharBeforeDigit(String s) { 
     if(null==s||s.length()==0) return null; 
     int cropIndex=Math.min(s.length(), 2);  
     if(!Character.isLetter(s.charAt(0))) return null; 
     if(cropIndex>1 && !Character.isLetter(s.charAt(1))) --cropIndex; 

     return s.substring(0,cropIndex); 
    } 

    public static void main(String[] args) { 
     System.out.println(getFirstTwoCharBeforeDigit("Az-a0")); 
    } 
} 
+1

您達到's.charAt(1)'字符串長度爲1,造成異常 –

+0

哦,是的!謝謝@索爾森。 – Damith

回答

1

我建議使用作爲Pattern類的API描述正則表達式

"^[a-z]{1,2}" 

@RunWith(Parameterized.class) 
public class ConsecutiveCharsTest { 

    @Parameters 
    public static Collection<Object[]> data() { 
     //@formatter:off 
     return Arrays.asList(new Object[][] { 
      {"abcd", "ab" }, 
      {"a", "a" }, 
      {"a0bc", "a" }, 
      {"0bcd", null }, 
      {"-123", null }, 
     }); 
     //@formatter:on 
    } 

    private final String input; 
    private final String expected; 

    public ConsecutiveCharsTest(String input, String expected) { 
     super(); 
     this.input = input; 
     this.expected = expected; 
    } 

    @Test 
    public void test() { 
     Pattern pattern = Pattern.compile("^[a-z]{1,2}"); 
     Matcher matcher = pattern.matcher(input); 
     if (matcher.find()) { 
      assertEquals(input, expected, matcher.group()); 
     } else { 
      assertNull("no Match expected", expected); 
     } 
    } 
} 
+1

建議模式僅適用於英語的受限子集。要允許任何字母應該使用\ p {IsAlphabetic}而不是[a-z]。 爲了更加精確,問題要求任何字符都不是數字。那將是\ D。 –

+0

@JonathanRosenne該模式匹配樣本。 YAGNI-Principle告訴我們這已經足夠了......另外'\ D'會失敗,因爲它會匹配最後一個樣本中的'-'。 –

+0

你是對的,但是當樣本不符合規格誰說要遵守他們哪一個? –

2

這似乎是工作(謝謝蒂莫西):

private static final java.util.regex.Pattern pattern = Pattern.compile("^[a-z]{1,2}"); 

private static String getFirstTwoChars(String string) { 
    if (string == null) { 
     return null; 
    } 
    java.util.regex.Matcher matcher = pattern.matcher(string); 
    return matcher.find() ? matcher.group(0) : null; 
} 
+0

也許''^ [a-zA-Z] {1,2}「'而不是'」^ [a-z] {1,2}「' –

1

我覺得用RegExp對於這個簡單的任務是太重,因爲額外的對象很多的在場景後面創建。我的解決方案的可讀性,但它具有更好的性能和最小的額外內存對象的創建:

public static String getFirstTwoCharBeforeDigit(String str) { 
    return str != null && !str.isEmpty() ? Character.isAlphabetic(str.charAt(0)) ? str.substring(0, str.length() > 1 && Character.isAlphabetic(str.charAt(1)) ? 2 : 1) : null : null; 
} 
1

只是爲了增加一個選擇:

public static String getFirstTwoCharBeforeDigit(String str) { 
    String firstTwo = str.substring(0,Math.min(str.length(), 2)).replaceAll("\\d*$", ""); 
    return firstTwo.chars().allMatch(Character::isLetter) && !firstTwo.isEmpty()? 
      firstTwo: 
      null; 
} 
+0

感謝您的幫助! – Damith

相關問題