Ruby Regex соответствует, если не экранировано с \ - PullRequest
3 голосов
/ 15 декабря 2008

Используя Ruby, я пытаюсь разбить следующий текст с помощью регулярного выражения

~foo\~\=bar =cheese~monkey

Где ~ или = обозначает начало матча, если оно не экранировано с \

Так должно совпадать

~foo\~\=bar

тогда

=cheese

1012 * тогда *

~monkey

Я думал, что следующее будет работать, но это не так.

([~=]([^~=]|\\=|\\~)+)(.*)

Какое выражение для регулярных выражений лучше использовать?

edit Точнее, приведенное выше регулярное выражение соответствует всем вхождениям = и ~

edit Рабочий раствор. Вот то, что я придумал, чтобы решить проблему. Я обнаружил, что Ruby 1.8 смотрит в будущее, но не имеет функциональности. Итак, немного осмотревшись, я наткнулся на этот пост в comp.lang.ruby и дополнил его следующим:

# Iterates through the answer clauses
def split_apart clauses
  reg = Regexp.new('.*?(?:[~=])(?!\\\\)', Regexp::MULTILINE)

  # need to use reverse since Ruby 1.8 has look ahead, but not look behind
  matches =  clauses.reverse.scan(reg).reverse.map {|clause| clause.strip.reverse}

  matches.each do |match|
    yield match
  end
end

1 Ответ

4 голосов
/ 15 декабря 2008

Что означает «убрать голову» в этом контексте?

Если вы хотите удалить все до определенного символа, это сделает:

.*?(?<!\\)=      // anything up to the first "=" that is not preceded by "\"
.*?(?<!\\)~      // same, but for the squiggly "~"
.*?(?<!\\)(?=~)  // same, but excluding the separator itself (if you need that)

Заменить на "", повторить, сделано.

Если в вашей строке ровно три элемента ("1=2~3") и вы хотите сопоставить их все сразу, вы можете использовать:

^(.*?(?<!\\)(?:=))(.*?(?<!\\)(?:~))(.*)$

matches:  \~foo\~\=bar =cheese~monkey
         |      1      |   2  |  3   |

В качестве альтернативы, вы разделяете строку с помощью этого регулярного выражения:

(?<!\\)[=~]

returns: ['\~foo\~\=bar ', 'cheese', 'monkey']   for "\~foo\~\=bar =cheese~monkey"
returns: ['', 'foo\~\=bar ', 'cheese', 'monkey'] for "~foo\~\=bar =cheese~monkey"
...