partita Rubino Regex se non è cavata con \
-
21-08-2019 - |
Domanda
Utilizzando Rubino Sto cercando di dividere il testo che segue con un Regex
~foo\~\=bar =cheese~monkey
Dove ~ o = indica l'inizio della partita a meno che sia fuggito con \
Così dovrebbe corrispondere
~foo\~\=bar
poi
=cheese
poi
~monkey
Ho pensato che il seguente avrebbe funzionato, ma non è così.
([~=]([^~=]|\\=|\\~)+)(.*)
Che cosa è una migliore espressione regex da usare?
modifica Per essere più precisi, quanto sopra regex trova tutte le occorrenze di = e ~
modifica Soluzione di lavoro. Ecco cosa mi è venuta per risolvere il problema. Ho scoperto che Ruby 1.8 è guardare avanti, ma non ha funzionalità lookbehind. Così, dopo aver guardato un po 'intorno, mi sono imbattuto in questo post in comp.lang.ruby e completato con il seguente:
# 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
Soluzione
Che cosa significa "togliere la testa" significa in questo contesto?
Se si desidera rimuovere tutto prima di un certo carattere, questo farà:
.*?(?<!\\)= // 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)
Sostituire con "", ripetere, fatto.
Se la stringa ha esattamente tre elementi ("1=2~3"
) e si desidera abbinare tutti in una volta, è possibile utilizzare:
^(.*?(?<!\\)(?:=))(.*?(?<!\\)(?:~))(.*)$
matches: \~foo\~\=bar =cheese~monkey
| 1 | 2 | 3 |
In alternativa, è dividere la stringa usando questo regex:
(?<!\\)[=~]
returns: ['\~foo\~\=bar ', 'cheese', 'monkey'] for "\~foo\~\=bar =cheese~monkey"
returns: ['', 'foo\~\=bar ', 'cheese', 'monkey'] for "~foo\~\=bar =cheese~monkey"