Преобразование регулярного выражения для вики-подобной разметки - PullRequest
0 голосов
/ 29 августа 2009

Рассмотрим следующий вход для разметки:

* Line 1
* Line 2
:* Line 2.1
:* Line 2.2
* Line 3

Это обычно кодируется как:

  <ul>
    <li>Line 1</li>
    <li>Line 2</li>
    <ul>
      <li>Line 2.1</li>
      <li>Line 2.2</li>
    </ul>
    <li>Line 3</li>
  </ul>

Мои вопросы:

  • Что было бы хорошим представлением для того же ввода, используя одну строку?
  • Что такое регулярное выражение для генерации соответствующего XHTML?

Например, формат однострочного ввода может быть:

> Line 1 > Line 2 >> Line 2.1 >> Line 2.2 > Line 3

С > - неупорядоченный разделитель элементов списка. Я выбрал >, потому что текст может содержать типичные знаки препинания. Использовать "(или другие подобные клавиши без 104 клавиш) было бы весело, но не так просто набрать.

Формат ввода строки также может быть:

[Line 1][Line 2 [Line 2.1][Line 2.2]][Line 3]

Обновление # 1 - Проблема немного проще. Количество гнезд может быть ограничено тремя. Общее решение для n-уровней глубины все равно было бы круто.

Обновление # 2 - XHTML, а не HTML.

Обновление # 3 - Другой возможный формат ввода.

Обновление # 4 - Java-решения (или просто регулярное выражение) приветствуются.

Обновление № 5

Пересмотренный код:

String in = " * Line 1 * Line 2 > * Line 2.1 * Line 2.2 < * Line 3";

String sub = "<ul>" + in.replace( " > ", "<ul>" ) + "</ul>";

sub = sub.replace( " < ", "</ul>" );

sub = sub.replaceAll( "( | >)\\* ([^*<>]*)", "<li>$2</li>" );

System.out.println( "Result: " + sub );

Печатает следующее:

Result: <ul><li>Line 1 </li>* Line 2<ul>* Line 2.1<li>Line 2.2</li></ul>* Line 3

Ответы [ 3 ]

3 голосов
/ 29 августа 2009

Ваш пример мне подходит.

 > Line 1 > Line 2 >> Line 2.1 >> Line 2.2 > Line 3

К сожалению, чистый RegEx не может отследить, на каком уровне вложенности вы находитесь, поэтому он не будет знать, куда помещать теги / UL .

Что-то вроде этого может работать:

 * Line 1 * Line 2 > * Line 2.1 * Line 2.2 < * Line 3

Здесь, больше и меньше, чем двигаться вверх и вниз по иерархии, и звездочки являются разделителями для пуль. Пробелы до и после каждого используются как своего рода escape-последовательность, поэтому вы все равно можете использовать эти символы буквально или для других целей, таких как курсив и полужирный, когда они не окружены пробелами.

Удар в RegEx:

 string ol = "<ul>" & RegEx.Replace(t, " > ", "<ul>") & "</ul>";
 ol = RegEx.Replace(ol, " < ", "</ul>");
 ol = RegEx.Replace(ol, "( |>)\\* ([^*<>]*)", "<li>\\2</li>"); 

Редактировать: Настроен для создания XHTML, закрывая теги LI, на основе комментария ниже. Также исправлен мой синтаксис C #.

Окончательное редактирование: Я думаю, что \ * и \ 2 в последней замене нужно экранировать для C #, исправляя. Также обратите внимание, что первые два вызова Replace () могут использовать String.Replace (), а не RegEx, что, вероятно, будет быстрее.

0 голосов
/ 01 сентября 2009

Решение

Ниже приводится рабочий раствор:

public class Test {
  public Test() {
  }

  public static void main( String[] args ) {
    String in = "= Line 1 = Line 2 > = Line 2.1 = Line 2.2 < = Line 3";

    in = in.replaceAll( "= ([^=<>]*)", "<li>$1</li>" );
    in = in.replace( ">> ", "><ul>" );
    in = in.replace( ">< ", "></ul>" );
    in = "<ul>" + in + "</ul>";
    System.out.println( in );
  }
}

Создает нужный фрагмент XHTML:

<ul><li>Line 1 </li><li>Line 2 </li><ul><li>Line 2.1 </li><li>Line 2.2 </li></ul><li>Line 3</li></ul>
0 голосов
/ 31 августа 2009

Я бы не рекомендовал использовать регулярные выражения в качестве инструмента синтаксического анализа и преобразования. Регулярные выражения, как правило, требуют больших затрат и не являются наиболее эффективным средством синтаксического анализа языка ... это то, что вы действительно просите его сделать. Вы создали такой простой язык, и вам следует относиться к нему как к такому. Я рекомендую написать настоящий, выделенный парсер для вашего кода форматирования в стиле WIKI. Поскольку вы можете ориентировать синтаксический анализатор именно на ваш язык, он должен быть более эффективным. Кроме того, вам не нужно создавать какое-то пугающее чудовище, которое является регулярным выражением для анализа вашего языка и обработки всех его нюансов. В долгосрочной перспективе вы получаете преимущества более четкого кода, лучшей управляемости и т. Д.

Предлагаю следующие ресурсы:

...