- In POSIX awk,
Is there a builtin function which can achieve either of the two objectives?
Não. Você pode conseguir o mesmo efeito, mas não com uma única função interna.
Does the
match
builtin function only find the leftmost and longest match?
Sim. Expressões regulares em POSIX awk
(e GNU awk
) são sempre gananciosas (ou seja, a correspondência mais longa sempre ganha).
To achieve the first objective, is it a correct way to repeatedly apply
match
to the suffix of the target string created by finding each match and removing the match and the prefix before it from the target string?
Sim, mas se você quiser 100% de compatibilidade com gsub()
, os detalhes serão bem complicados.
Is https://gist.github.com/mllamazing/a40946fcf8211a503bed a correct implementation?
Principalmente, se você remover a linha do gsub . O diabo está nos detalhes: o código irá fazer um loop se regex
for uma string vazia. O awk
clássico não permitia regexps vazios, mas o IIRC nawk
sim. Para corrigir isso, você poderia fazer algo assim:
function FindAllMatches(str, regex, match_arr) {
ftotal = 0;
ini = RSTART;
leng = RLENGTH;
delete match_arr;
while (str != "" && match(str, regex) > 0) {
match_arr[++ftotal] = substr(str, RSTART, RLENGTH)
str = substr(str, RSTART + (RLENGTH ? RLENGTH : 1))
}
RSTART = ini;
RLENGTH = leng;
}
Isso não é 100% compatível com gsub()
, porque
$ echo 123 | awk '{ gsub("", "-") } 1'
-1-2-3-
enquanto a função acima encontra apenas 3 correspondências (ou seja, ela perde o jogo no final).
Você pode tentar isso:
function FindAllMatches(str, regex, match_arr) {
ftotal = 0;
ini = RSTART;
leng = RLENGTH;
delete match_arr;
while (match(str, regex) > 0) {
match_arr[++ftotal] = substr(str, RSTART, RLENGTH)
if (str == "") break
str = substr(str, RSTART + (RLENGTH ? RLENGTH : 1))
}
RSTART = ini;
RLENGTH = leng;
}
Isso corrige o problema acima, mas quebra outros casos: se str = "123"
e regex = "[1-9]*"
a função encontrar duas ocorrências, 123
e a string vazia no final, enquanto gsub()
encontrar apenas uma, 123
.
Pode haver outras diferenças semelhantes, que não posso me incomodar em caçar agora.
In Gawk,
does
array
after a callpatsplit(string, array, fieldpat, seps)
store the matches as required in the second objective?
Principalmente sim. No entanto, casos de canto relacionados a regexps podem ser inesperadamente sutis. Pode haver algumas diferenças, como acima.
Can the locations of the match location be found from
array
andseps
, based on thatseps[i]
is the separator string betweenarray[i]
andarray[i+1]
?
Sim.