Erzwingen, dass Bash die Perl RegEx Engine verwendet


11

Wie Sie vielleicht bereits wissen, werden viele der Funktionen, die moderne RegEx-Engines unterstützen (Rückverweise, Lookaround-Behauptungen usw.), von der Bash RegEx-Engine nicht unterstützt. Es folgt ein einfaches Bash-Skript, das ich gerade erstellt habe, um zu erklären, was mein Endziel ist:

#!/bin/bash

# Make sure exactly two arguments are passed.
if [ $# -lt 2 ]
then
    echo "Usage: match [string] [pattern]"
    return
fi

variable=${1}
pattern=${2}

if [[ ${variable} =~ ${pattern} ]]
then
    echo "true"
else
    echo "false"
fi

So gibt beispielsweise der folgende Befehl false zurück:

. match.sh "catfish" "(?=catfish)fish"

Der exakt gleiche Ausdruck findet eine Übereinstimmung, wenn er in einem Perl- oder JavaScript-Regex-Tester verwendet wird.

Rückreferenzen (zB (Ausdruck1) (Ausdruck2) [] \ 1 \ 2) stimmen ebenfalls nicht überein.

Ich bin einfach zu dem Schluss gekommen, dass mein Problem nur gelöst werden kann, wenn bash gezwungen wird, eine Perl-kompatible RegEx-Engine zu verwenden. Ist das machbar? Wenn ja, wie würde ich vorgehen, um das Verfahren durchzuführen?


5
Warum verwenden Sie nicht einfach Perl anstelle von Bash für Skripte? Und warum ist diese Frage mit Javascript gekennzeichnet?
Marco

Weil die Verwendung von Bash in meiner Situation ein Muss ist. Und ich habe versehentlich JavaScript markiert. Ich habe es entfernt :)
Fadi Hanna AL-Kass

2
Warum benutzt du nicht grepmit -Poder mit sed?
Cuonglm

2
Aber Sie erklären niemals die Situation / das Problem, die Sie zu dem Schluss gebracht haben, dass die Shell etwas tun muss, was sie einfach nicht kann. Es gibt einen besseren Weg.
llua

Ich finde , dass Rückreferenzierungen tun Arbeit in bash 4.3.x (Ubuntu 14.04), aber nicht in bash 3.2x (OS X). Hier ist mein Testbefehl:re="([a-z])[0-9]\1"; [[ a1a =~ $re ]] && echo ${BASH_REMATCH[0]}
Digital Trauma

Antworten:


14

Bash unterstützt derzeit keine Methode, mit der Sie dies tun können. Sie haben folgende Möglichkeiten:

  1. Verwenden Sie Perl
  2. Verwenden grep [-P|--perl-regexp]
  3. Verwenden Sie die Bash-Funktionalität, um sie zu codieren

Ich denke, ich würde mit # 2 gehen und versuchen, das grepzu bekommen, was ich funktional will. Für die Rückreferenzierung können Sie Folgendes tun grep:

$ echo 'BEGIN `helloworld` END' | grep -oP '(?<=BEGIN `).*(?=` END)'
helloworld

-o, --only-matching       show only the part of a line matching PATTERN
-P, --perl-regexp         PATTERN is a Perl regular expression

(?=pattern)
    is a positive look-ahead assertion
(?!pattern)
    is a negative look-ahead assertion
(?<=pattern)
    is a positive look-behind assertion
(?<!pattern)
    is a negative look-behind assertion 

Verweise


Ich wusste ehrlich gesagt nicht, dass Grep einen [-P|--perl-regexp]Token hat. Vielen Dank :-)
Fadi Hanna AL-Kass

@ FadiHannaAL-Kass - herzlich willkommen. Danke für die Frage.
slm

2
Für die Nachwelt enthält nur GNU grep die -POption, und sie ist nicht universell. FreeBSDs grep basiert auf GNU, aber in der Dokumentation heißt es "Diese Option wird in FreeBSD nicht unterstützt". In OSX basiert grep ebenfalls auf GNU, aber die -POption wird in der Manpage nicht einmal erwähnt. Und auf anderen Unix-Systemen, deren Grep nicht GNU ist, ist es unwahrscheinlich, dass Sie -Püberhaupt etwas sehen. Wenn Sie die Möglichkeit haben, dass Portabilität in Zukunft für Sie nützlich sein könnte, empfehle ich, solche betriebssystemspezifischen Optionen zu vermeiden.
Ghoti

pcregrepist auch eine Option, falls verfügbar.
Wildcard

Es ist zu beachten, dass zsh genau das tut, was das OP angefordert hat, solange die REMATCH_PCREOption festgelegt ist.
Tim Peoples

0

Man könnte es gebrauchen pcregrep. Es kommt mit dem Paket pcrein CentOS und pcregrepin Ubuntu.

grep -P könnte dieses Problem je nach Betriebssystem / Version haben:

-P, --perl-regexp
              Interpret PATTERN as a Perl regular expression.  This is highly experimental and grep -P may warn of unimplemented features.
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.