Я пытаюсь извлечь номера длиной от 3 до 5 из длинной строки текста. Позволь мне объяснить
Скажем, есть строка, подобная этой 123456
и я хочу извлечь все число, которое находится между выводами длины 3 и 5, будет
123
234
345
456
1234
2345
3456
12345
23456
Я могу запустить несколько регулярных выражений, которые индивидуально находят длины, но может быть лучший способ сделать это, чем то, что я делаю.
import java.io.IOException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RegexTestHarness {
public static void main(String[] args) throws IOException {
String data = "123456";
Matcher m = Pattern.compile("\\d{3}").matcher(data);
// m = Pattern.compile("\\d{4}").matcher(data);
// m = Pattern.compile("\\d{5}").matcher(data);
int position = 0;
while (m.find(position++)) {
System.out.println(m.group());
}
}
}
Преждевременная оптимизация Идея - я могу сопоставить все с 5, а затем запускать матчи меньшего размера по результатам. Таким образом, я сокращаю время чтения данных, над которыми в моем случае является внешний источник.
Вы можете сделать это с помощью одного регулярного выражения. Просто найти в мире.
Группы захвата печати 1,2,3, если их длина больше 0
# "(?=(\\d{3}))(?=(\\d{4}))?(?=(\\d{5}))?"
(?=
( \d{3} ) # (1)
)
(?=
( \d{4} ) # (2)
)?
(?=
( \d{5} ) # (3)
)?
Тест на Perl
while ( '123456' =~ /(?=(\d{3}))(?=(\d{4}))?(?=(\d{5}))?/g )
{
print "$1\n";
if ( length ($2) ) {
print "$2\n";
}
if ( length ($3) ) {
print "$3\n";
}
}
Выход >>
123
1234
12345
234
2345
23456
345
3456
456
Это выглядит намного сложнее с регулярным выражением. Если вам не нужно использовать его, пройдите через каждую из исходных позиций и извлеките числа:
// If this string is just plain numbers, skip the dataArray and the
// for (String s: dataArray) and replace the s in the loops with data's
String data = "123456 some other datas 654321";
String[] dataArray = data.split("\\D+");
for (String s: dataArray){
for (int length = 3; length <= 5; length++){
for (int index = 0; index <= s.length() - length; index++) {
int maxIndex = index + length;
System.out.println(s.substring(index, maxIndex));
}
}
}
Вывод:
123
234
345
456
1234
2345
3456
12345
23456
654
543
432
321
6543
5432
4321
65432
54321
Попробуйте это решение только для 3-5 матчей. Я использую lookahead, чтобы найти совпадающее совпадение со строкой. Здесь я использовал три регулярных выражения.
String text = "123456";
Pattern pattern = Pattern.compile("(?=(\\d\\d\\d))(?=(\\d\\d\\d\\d?))(?=(\\d\\d\\d\\d?\\d?))");
Matcher m = pattern.matcher(text);
// taking out all the captures from the Matcher
List<String> list = new ArrayList<String>();
while (m.find()) {
list.add(m.group(1));
list.add(m.group(2));
list.add(m.group(3));
}
// making the list unique using HashSet
list = new ArrayList<String>(new HashSet<String>(list));
// printing
for(String s : list){
System.out.println(s);
}
// output is not sorted, if you want you can sort the List<>
"1234 123"
? Вы могли бы действительно хотеть дубликаты.