У меня есть строка с разметкой, которую мне нужно найти с помощью Java.
например.
string = abc<B>def</B>ghi<B>j</B>kl
desired output..
segment [n] = start, end
segment [1] = 4, 6
segment [2] = 10, 10
или лучше, регулярное выражение типа <b> [^ <] + </b> для соответствия каждому сегменту




Для этого прекрасно подойдут регулярные выражения.
Обратитесь к вашему JavaDoc для
Примечание. StringTokenizer - это не то, что вам нужно, поскольку он разбивается на символы, а не на строки - разделитель строк представляет собой список символов, любой из которых будет разделен. Это хорошо для очень простых случаев, например, для однозначного списка, разделенного запятыми.
StringTokenizer предоставит вам отдельные токены, если вы захотите разделить строку определенной строкой. Или вы можете использовать метод split () в String для получения отдельных строк. Чтобы получить разные массивы, вам нужно вставить регулярное выражение.
спасибо, Маркус .. для справки я нашел это .. StringTokenizer - это устаревший класс, который сохранен по соображениям совместимости, хотя его использование не рекомендуется в новом коде. Рекомендуется, чтобы любой, кто ищет эту функциональность, использовал вместо этого метод разделения String или пакет java.util.regex.
StringTokenizer разбивается на символы, а не на строки - разделитель строк представляет собой список символов, любой из которых будет разделен. Это хорошо для очень простых случаев, например, для однозначного списка, разделенного запятыми.
StringTokenizer принимает в качестве аргумента всю строку, и это не очень хорошая идея для больших строк. Вы также можете использовать StreamTokenizer
Еще нужно посмотреть Сканер.
Учитывая ваш пример, я думаю, что я бы использовал регулярное выражение, и особенно я бы посмотрел на функциональность группировки, предлагаемую Matcher.
Том
String inputString = "abc<B>def</B>ghi<B>j</B>kl";
String stringPattern = "(<B>)([a-zA-Z]+)(<\/B>)";
Pattern pattern = Pattern.compile(stringPattern);
Matcher matcher = pattern.matcher(inputString);
if (matcher.matches()) {
String firstGroup = matcher.group(1);
String secondGroup = matcher.group(2);
String thirdGroup = matcher.group(3);
}
это здорово - соответствие всего сегмента, а не только начальных / конечных тегов по отдельности
когда я пробовал ваше регулярное выражение в gskinner.com/RegExr, казалось, что сегменты не совпадают с чем-то простым, например, <B>. + </B> совпадает с первым <B> и последним </B>, так что это не способ
Вы . будет соответствовать чему угодно, поэтому он должен быть более строгим. Следовательно, я использую [a-zA-Z]. Я уверен, что после небольшой настройки и некоторого понимания того, чего можно ожидать между <B> и </B>, вы сможете это исправить.
ah - заменить [a-zA-Z] на [a-zA-Z] +
В этом регулярном выражении не должно быть обратной косой черты. Помещая их перед каждой круглой скобкой, вы говорите регулярному выражению, чтобы оно соответствовало буквальным скобкам. Тот, что находится перед косой чертой, ничего не вредит, но в этом нет необходимости.
Алан, ты прав. Я думаю, они вам понадобятся для какой-то другой реализации регулярного выражения. Мне нужна дополнительная обратная косая черта для прямой косой черты, чтобы сообщить Java, что обратная косая черта является буквальной. Что за палава. :)
Это немного «грубая сила» и делает некоторые предположения, но это работает.
public class SegmentFinder
{
public static void main(String[] args)
{
String string = "abc<B>def</B>ghi<B>j</B>kl";
String startRegExp = "<B>";
String endRegExp = "</B>";
int segmentCounter = 0;
int currentPos = 0;
String[] array = string.split(startRegExp);
for (int i = 0; i < array.length; i++)
{
if (i > 0) // Ignore the first one
{
segmentCounter++;
//this assumes that every start will have exactly one end
String[] array2 = array[i].split(endRegExp);
int elementLenght = array2[0].length();
System.out.println("segment["+segmentCounter +"] = "+ (currentPos+1) +","+ (currentPos+elementLenght) );
for(String s : array2)
{
currentPos += s.length();
}
}
else
{
currentPos += array[i].length();
}
}
}
}
Ваш ввод похож на ваш пример, и вам нужно поместить текст между определенными тегами? Тогда простая строка StringUtils.substringsBetween (yourString, "<B>", "</B>") с использованием пакета apache commons lang (http://commons.apache.org/lang/) должна выполнить свою работу.
Если вам нужно более общее решение для разных и, возможно, вложенных тегов, вам может потребоваться анализатор, который принимает ввод html и создает из него XML-документ, например NekoHTML, TagSoup, jTidy. Затем вы можете использовать XPath в XML-документе для доступа к содержимому.
Мне нужно получить позиции «<B>» и «</B>» в количестве символов, не включая эти теги. - см. пример в вопросе
выглядит как регулярное выражение из пакета java.util.regex, плюс некоторые простые математические вычисления - способ продолжить это