Этот модульный тест извлекает содержание предложения путем сопоставления согласованных групп (обратите внимание на круглые скобки) с помощью индекса группы. Если шаблон соответствует заданной строке, то вся строка ввода - это группа 0. В данном примере сопоставленный message
находится в индексе группы 1 и name
с индексом 2. В качестве альтернативы вы можете определить именованные группы.
@RunWith(Parameterized.class)
public class Snippet {
private final String testSentence;
private final String[][] expectedResult;
public Snippet(String testSentence, String[][] expectedMessages) {
this.testSentence = testSentence;
this.expectedResult = expectedMessages;
}
private String[][] extractSentenceContent(String sentence) {
Pattern pattern = Pattern.compile("Send\\s([\\p{Alpha}\\s]+)\\sto\\s([\\p{Alpha}\\s]+)");
Matcher matcher = pattern.matcher(sentence);
String[][] result;
if(matcher.matches()) {
result = new String[][] {{"message", matcher.group(1)}, {"name", matcher.group(2)}};
} else {
result = null;
}
return result;
}
@Test
public void testRegex(){
String[][] actualResult = extractSentenceContent(testSentence);
TestCase.assertTrue(Arrays.deepEquals(expectedResult, actualResult));
}
@Parameters
public static Iterable<?> getTestParameters(){
Object[][] parameters = {
{"Send Hi there to Jesus", new String[][] {{"message", "Hi there"}, {"name", "Jesus"}}}
};
return Arrays.asList(parameters);
}
}
Есть ли способ, чтобы получить имя группы захвата из шаблона, без жесткого кодирования «сообщение» и «имя»?
Одноранговое решение могло бы использовать String.format для вставки динамических имен групп захвата, как это:
private String[][] extractSentenceContent(String sentence, String captureGroupA, String captureGroupB) {
String pattern = String.format("^Send\\s(?<%s>[\\p{Alpha}\\s]+)\\sto\\s(?<%s>[\\p{Alpha}\\s]+)$", captureGroupA, captureGroupB);
Matcher matcher = Pattern.compile(pattern).matcher(sentence);
String[][] result;
if(matcher.matches()) {
result = new String[][] {
{captureGroupA, matcher.group(captureGroupA)},
{captureGroupB, matcher.group(captureGroupB)}
};
} else {
result = null;
}
return result;
}
Если вы не знакомы с Regex, то есть [ 'MessageFormat.parse'] (https: //docs.oracle.com/javase/8/docs/api/java/text/MessageFormat.html#parse(java.lang.String)). Однако я бы использовал [Regex] (https://docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html). 'Отправить \\ s + (?. *?) \\ s + to \\ s + (? . *)' Должно это сделать. –
Отредактированы теги вопроса. Тэг шаблона проектирования здесь неуместен. Прочтите описание тега. – CKing
'MessageFormat.parse' - это наоборот, что я хочу. Я не очень хорошо знаком с регулярным выражением, какие-то намеки? –