いくつかのテキストでパターン(ネストされたパラメータを含む)を囲むためにsedで使用されるいくつかの正規表現を見つけようとしています。
基本的な例は次のとおりです。
length(bill_cycle)
正規表現は以下を提供しなければなりません。
length(cast(bill_cycle as string))
ここでは、で始まるものを検索し、関連するエンディングをlength(
探します。その後、真ん中のコンテンツ)
length(
bill_cycle
cast(bill_cycle as string)
変数(この場合some(somethiing)
)に次のネストされたパラメータがありますが、
length(some(somethiing))
正規表現は以下を提供しなければなりません。
length(cast(some(somethiing) as string))
私はUNIXスクリプトや動作する他のコマンドで開いています。どんな助けでも大変感謝します。
答え1
Perlが救出に来る!
perl -MText::Balanced=extract_bracketed \
-ne 'if (/length(\(.*)/) {
($arg) = (extract_bracketed(($1 =~ /\((.*)\)/)[0]))[1];
print "length(cast($arg as string))\n";
} else { print }' -- input.file > output.file
コアモジュールを使用してください。テキスト::バランス文字列からバランス区切り文字を含む部分文字列を抽出します。
答え2
使用perl
と再帰マッチング:
$ cat ip.txt
length(bill_cycle)
length(some(somethiing))
$ perl -pe 's/length(\(((?:[^()]++|(?1))++)\))/length(cast($2 as string))/' ip.txt
length(cast(bill_cycle as string))
length(cast(some(somethiing) as string))
バラよりhttps://www.rexegg.com/regex-recursion.html再帰がどのように機能するかを理解します。
答え3
これは、括弧のパターンマッチングを使用せずにそれを計算するawkスクリプトです。また、各行の複数の項目と一致します。
BEGIN {
p = "length"
}
{
row = $0
while (row ~ p"\\(") {
# get the substring from pattern to the end of the line
# and split to array with closing parenthesis separator
x = substr(row, index(row,p) + length(p))
split(x, a, ")")
res = p
# loop for array items and append them to substring
# until we have a string with same number of
# opening and closing parentheses.
for (i=1;i<=length(a);i++) {
res = res a[i] (i==length(a)? "": ")")
if (gsub(/\(/,"(",res) == gsub(/\)/,")",res)) {
print res
break
}
}
# will test again the rest of the row
row = substr(x, length(p))
}
}
いくつかの基本的なテスト
> cat file
some text length(a(b)) testing another occurence length(a))
function(length(c(d(e(f(1), 2)))) testinglength(x)
x length(y))
x length(((y))
length(length(1))
> awk -f tst.awk file
length(a(b))
length(a)
length(c(d(e(f(1), 2))))
length(x)
length(y)
length(length(1))