我想从字符串中获取两个字符(不是数字),直到第一个数字出现。字符串可能是任何,也将包含数字。我只需要注意前两个索引即可。一点棘手的部分是说第二个索引包含一个数字,然后只需要考虑第一个字符。
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"));
}
}
这似乎有效(谢谢蒂莫西):
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;
}
我建议使用正则表达式,如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);
}
}
}
我认为,将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;
}
只是添加另一种选择:
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;
}