2016-05-04 4 views
2

Нужна функция, чтобы избежать строки, содержащей операторы выражения регулярного выражения в awk-скрипте.awk: функция для вызова операторов регулярных выражений из строки

Я наткнулся на это 'уродливый' решение:

function escape_string(str) 
{ 
    gsub(/\\/, "\\\\", str); 
    gsub(/\./, "\\.", str); 
    gsub(/\^/, "\\^", str); 
    gsub(/\$/, "\\$", str); 
    gsub(/\*/, "\\*", str); 
    gsub(/\+/, "\\+", str); 
    gsub(/\?/, "\\?", str); 
    gsub(/\(/, "\\(", str); 
    gsub(/\)/, "\\)", str); 
    gsub(/\[/, "\\[", str); 
    gsub(/\]/, "\\]", str); 
    gsub(/\{/, "\\{", str); 
    gsub(/\}/, "\\}", str); 
    gsub(/\|/, "\\|", str); 

    return str; 
} 

Все лучшие идеи?

+1

Да, но почему? Когда люди пытаются избежать метасимволов регулярного выражения, это почти всегда, потому что они действительно хотят что-то делать со строками вместо регулярных выражений, но не знают, как выполнять строковые операции, поэтому они ошибочно пытаются избежать всех метасимволов RE, чтобы они могли использовать их как строки в операциях регулярного выражения (например, 'match ($ 0, regexp)') вместо использования as-is в строковых операциях (например, 'index ($ 0, string)'). –

+0

@ EdMorton да, ** почти ** всегда, не всегда. Цель здесь состоит в том, чтобы текстовые файлы proccess, содержащие два столбца, такие как этот: http://pastebin.com/U9Sjq53W - Итак, я написал следующий скрипт awk: http://pastebin.com/AwHmHS74 для обработки таких файлов. Я ищу строку 'запись, сделанную, когда T.M.A-1 приветствовал' - http://pastebin.com/sMDQxfcE - в этом случае простые операции с строкой не могут решить проблему. – Lacobus

ответ

3

Вы можете просто использовать одиночный gsub используя класс символов так:

function escape_string(str) { 
    gsub(/[\\.^$(){}\[\]|*+?]/, "\\\\&", str) 
} 

& возвращается ссылка на совпавшей строки и \\\\ для побега матч.

+2

Я думаю, что вы можете избежать экранирования '' '' внутри класса символов, а если вы сначала перечислите '' '', то также не нужно экранировать: 'gsub (/ [] [\\.^$() {} | * +?] /, ... '. Является ли это на самом деле более четким - это отдельное обсуждение. –

+0

Да, я знаю, что, разместив их на 1-й и 2-й позиции, мы можем избежать экранирования. Я просто избегал этого, потому что это несколько запутывает, поскольку кажется, что Используются 2 разных класса символов :) – anubhava