Регулярное выражение литерал-текст span - PullRequest
2 голосов
/ 03 декабря 2010

Есть ли способ указать регулярному выражению блок текста, который нужно искать явно? Я спрашиваю, потому что мне нужно сопоставить очень очень длинный фрагмент текста, который содержит всевозможные метасимволы (и (и должен точно соответствовать), за которыми следуют некоторые гибкие элементы (достаточные для использования регулярных выражений), за которыми следует больше текста это должно быть точно согласовано.

Промыть, повторить.

Само собой разумеется, я действительно не хочу проходить через все это и должен избегать каждого метасимвола. Это просто делает это медведем, чтобы читать. Есть ли способ обернуть эти порции, чтобы мне не пришлось это делать?

Edit:

В частности, я использую Tcl, и под "метасимволами" я подразумеваю, что есть все виды длинных строк, таких как "**$^{*$%\)". Я действительно не хотел бы избежать этого. Я имею в виду, это добавило бы тысячи символов в строку. Имеет ли Tcl регулярное выражение метасимвол литерального текста?

Ответы [ 4 ]

4 голосов
/ 04 декабря 2010

Обычный способ сделать это в Tcl - использовать вспомогательную процедуру для выполнения экранирования, например:

proc re_escape str {
    # Every non-word char gets a backslash put in front
    regsub -all {\W} $str {\\&}
}

set awkwardString "**$^{*$%\\)"
regexp "simpleWord *[re_escape $awkwardString] *simpleWord" $largeString

Если у вас есть целая литеральная строка, у вас есть две другие альтернативы:

regexp "***=$literal" $someString
regexp "(?q)$literal" $someString

Однако оба они допускают только шаблоны, которые являются чистыми литералами;Вы не можете смешивать шаблоны и литералы таким образом.

0 голосов
/ 03 декабря 2010

Нет, tcl не имеет такой возможности.

Если вы беспокоитесь о читабельности, вы можете использовать переменные и команды для построения своего выражения.Например, вы можете сделать что-то вроде:

set fixed1 {.*?[]}  ;# match the literal five-byte sequence .*?[]
set fixed2 {???}    ;# match the literal three byte sequence ???
set pattern "this.*and.*that"

regexp "[re_escape $fixed1]$pattern[re_escape $fixed2]"

Вам нужно будет указать определение для re_escape, но решение должно быть довольно очевидным.

0 голосов
/ 03 декабря 2010

Регулярное выражение Tcl можно указать с помощью метасинтаксической директивы q, чтобы указать, что выражение является литеральным текстом:

% set string {this string contains *emphasis* and 2+2 math?}
% puts [regexp -inline -all -indices {*} $string]
couldn't compile regular expression pattern: quantifier operand invalid
% puts [regexp -inline -all -indices {(?q)*} $string]
{21 21} {30 30}

Это, однако, относится ко всему выражению.

Что бы я сделал, это перебрал возвращенные индексы, используя их в качестве аргументов для [string range], чтобы извлечь другие вещи, которые вы ищете.

0 голосов
/ 03 декабря 2010

Я верю, что Perl и Java поддерживают escape \ Q \ E.поэтому

\Q.*.*()\E

.. будет фактически соответствовать литералу ".*.*()"

ИЛИ

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

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