Неожиданное поведение Ruby Regexp - PullRequest
0 голосов
/ 11 мая 2018

Учитывая следующую строку, str:

\begin{align*}
\intertext{Here is some text}
x^{2}+2x+3=2\\
\intertext{Here is some more}
\end{align*}

Я хотел бы переместить строки текста вне среды выравнивания, например так:

Here is some text
\begin{align*}
x^{2}+2x+3=2\\
\end{align*}
Here is some more

Обратите внимание, что яэто нужно делать только тогда, когда интертекст появляется непосредственно перед или после \ begin {что-то} или \ end {что-то}.Имея это в виду, я написал следующие регулярные выражения:

begin_align = /\\begin\{([^}]*)\}\n\\intertext\{([^}]*)\}/m
end_align = /\\intertext\{([^}]*)\}\n\\end\{([^}]*)\}/m

Из-за сгруппированных элементов в скобках, когда я вызываю m = str.match(begin_align), я могу получить m[0] (совпавшая строка), m[1](которая должна быть заданной средой, align* в этом примере) и m[2], которая должна быть текстом внутри интертекста.Если я напишу str.match(m[0]), я получу nil.Зачем?

Я нашел способ обойти это: если я вместо этого позвоню str.match(Regexp.quote(m[0])), я получу совпадение. Однако , если я тогда попытаюсь заменить этот матч на str.sub(Regexp.quote(m[0]),''), скажем, ничего не произойдет.Если вместо этого я напишу str.sub(m[0],''), я получу ожидаемый результат.Как так?

Пока я пытался отладить этот пример, я заметил кое-что еще, что я не могу понять.Если я напишу "\\begin{align".match("\\begin{align"),
, я не получу соответствия, несмотря на то, что они одинаковые строки.Если я «уйду» от второго \\ как:
"\\begin{align".match("\\\\begin{align"),
, тогда я получу совпадение.Если я то попробую поставить звездочку
"\\begin{align*".match("\\\\begin{align*"),
получу #<MatchData "\\begin{align">: звездочка игнорируется.Я должен избежать второй звездочки с \\*.Что происходит?

1 Ответ

0 голосов
/ 11 мая 2018

m[0]:

\\begin{align*}\n\\intertext{Here is some text}

Примечание по .sub():

Шаблон обычно Regexp;если задано значение String, любые метасимволы регулярного выражения, которые он содержит, будут интерпретироваться буквально.

Таким образом, m[0] содержит *, который является квантификатором.Заданный как '*' до .sub(), он означает не что иное, как буквальный * символ.Но значение .match() как '*' интерпретируется как квантификатор и причина для str.match('*'), чтобы выдать ошибку.align* в контексте регулярного выражения означает строку alig, предшествующую любому количеству n символов.

Так что для работы .match() вам нужно заботиться о таких специальных символах, но для .sub() это простобеспорядок для использования Regexp.quote и передачи его в виде строки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...