Regex, чтобы найти разметку - PullRequest
0 голосов
/ 02 февраля 2019

Я уверен, что кто-то уже задавал этот вопрос, но я не знаю, какие слова искать в Google, чтобы найти эти ответы.

Мне нужно «перевести» текст с разметкой в ​​html (илиRTF или XAML).Разметка для "жирный" является *.Если я хочу, чтобы жирный текст содержал литерал *, я должен замаскировать его обратной косой чертой.

Итак, размеченный текст ...

This is *ju\*st* a test.

...should перевести на «Это ju * st тест».

Я ищу шаблон регулярного выражения, чтобы все совпадения для «перевода» были выделены жирным шрифтом внутри моей разметкитекст.

Прямо сейчас я застрял с этим (буквальная звезда, за которой следуют один или несколько символов, которые не являются звездой (как можно меньше), за которыми следует буквальная звезда)

\*[^*]+?\*

Но как я могу улучшить часть «один или несколько символов, которые не являются звездами», чтобы не останавливаться на звездах, которым предшествует обратная косая черта?

Я хочу использовать это регулярное выражение вПроект .NET, в случае различий между языками.

Ответы [ 2 ]

0 голосов
/ 03 февраля 2019

Вы можете использовать

(?<=(?<!\\)(?:\\{2})*)\*[^\\*]*(?:\\.[^\\*]*)*\*

См. Демо .NET regex .

Подробности

  • (?<=(?<!\\)(?:\\{2})*) - позитивный взгляд сзади, который гарантирует, что прямо перед текущей локацией нет \ escape-символа.Другими словами, оно соответствует местоположению, которому непосредственно предшествует:
    • (?<!\\) - без \ char, за которым следует
    • (?:\\{2})* - любые ноль или более повторений двойных обратных косых черт
  • \* - * char
  • [^\\*]* - ноль или более символов, отличных от \ и *
  • (?: - начало сопоставления группы без захвата ...
    • \\. - любой символ (кроме новой строки, скомпилируйте шаблон с помощью RegexOptions.Singleline, чтобы разрешить любой экранированный символ), экранированный с помощью \ char
    • [^\\*]* - ноль или более символов, отличных от \ и *
  • )* - ноль или более раз
  • \* - * char.
0 голосов
/ 02 февраля 2019

Вы хотите сопоставить звезду разметки с другой звездой разметки.На вашем языке разметки буквальная звезда на самом деле не только *, но \*.В регулярном выражении это переводится как \\\*: обратный слеш, который должен быть экранирован, затем звезда, который также должен быть экранирован.

Поэтому в своем шаблоне необходимо указать, что вы ищете звезда разметки , в отличие от буквальной звезды .

\*.*[^\\]\*

\*             a markup star
  .*           followed by any character
    [^\\]\*    then a markup star, that is, one not escaped by a backslash

Это немного не так, потому что .* является жадным, поэтому в "*ju\*st* *ju\*st*, он будет соответствовать всей строке, от первой до последней звезды.

Вы можете использовать ленивую / не жадную версию модификатора звезды: *? в большинстве двигателей.Таким образом, это становится:

\*.*?[^\\]\*

\*             a markup star
  .*?          followed by any character, but as few as possible
     [^\\]\*   then a markup star, that is, one not escaped by a backslash

Небольшая попытка с Python:

>>> s = r"*ju\*st* *ju\*st*"
>>> re.match(r"\*.*[^\\]\*", s)
<re.Match object; span=(0, 17), match='*ju\\*st* *ju\\*st*'>
>>> re.match(r"\*.*?[^\\]\*", s)
<re.Match object; span=(0, 8), match='*ju\\*st*'>

Если ваш движок регулярных выражений не поддерживает ленивые модификаторы, вам нужно явно указать это поведение:

\*([^*]|\\\*)*[^\\]\*

\*                       a markup star
  (                      then either...
   [^*]                  ...any character but a star...
       |                 ...or...
        \\\*             ...a star prefix by a backslash, ie a literal star
            )*           any number
              [^\\]\*    then a markup star
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...