Ich versuche, mithilfe der in Bash integrierten Regex-Funktion nur den Text abzugleichen, der innerhalb der HTML-Tags enthalten ist:
string='<span class="circle"> </span>foo</span></span>'
regex='<span class="circle"> </span>(.+?)</span>'
[[ $string =~ $regex ]]
echo "${BASH_REMATCH[1]}"
Aber das Spiel fesselt immer wieder foo</span>
.
Im Internet gibt es so viele Beispiele für sed und grep, dass ich zu Bashs eigenem regulären Ausdruck nicht viel Dokumentation gefunden habe.
Antwort1
Es gibt einen Grund, warum das Internet voll von alternativen Ansätzen ist. Ich kann mir keine Situation vorstellen, in der Siegezwungenum hierfür Bash zu verwenden. Warum nicht eines der für diese Aufgabe entwickelten Tools verwenden?
Wie dem auch sei, soweit ich weiß, gibt es keine Möglichkeit, mit dem =~
Operator nicht-gierige Übereinstimmungen zu erzielen. Das liegt daran, dass er nicht die interne Regex-Engine von Bash verwendet, sondern die C-Engine Ihres Systems, wie in definiert man 3 regex
. Dies wird in erklärt man bash
:
An additional binary operator, =~, is available, with the same prece‐
dence as == and !=. When it is used, the string to the right of the
operator is considered an extended regular expression and matched
accordingly (as in regex(3)).
Sie können jedoch mehr oder weniger tun, was Sie wollen (wobei Sie bedenken müssen, dass dies wirklichnichteine gute Möglichkeit zum Parsen von HTML-Dateien) mit einem leicht anderen regulären Ausdruck:
string='<span class="circle"> </span>foo</span></span>'
regex='<span class="circle"> </span>([^<]+)</span>'
[[ $string =~ $regex ]];
echo "${BASH_REMATCH[1]}"
Das Obige wird foo
wie erwartet zurückgegeben.
Antwort2
Ich weiß nicht, ob die regulären Ausdrücke von Bash nicht gierig übereinstimmen wie Perl, also verwenden Sie eine Perl-Regex-Engine:
$ grep -oP '<span class="circle"> </span>\K.+?(?=</span>)' <<<"$string"
foo