sed
、awk
またはgrep
を使用して複数行のパターンマッチングを実行することは可能ですか?たとえば、{
と}
の間のすべての行を取得したいとします。
だからそれは一致することができるはずです
1. {}
2. {.....}
3. {.....
.....}
最初の質問では、例として<p>
を使用しました。 {
および}
を使用するように質問を編集しました。
上記のアドバイスに同意しますが、小さいか完全にアドホックではないパーサーを取得する必要があるということですが、中括弧とsedの間の複数行ブロックを一致させることは(かろうじて;-)可能です。
これは、sedコードのデバッグバージョンです。
sed -n '/[{]/,/[}]/{
p
/[}]/a\
end of block matching brace
}' *.txt
いくつかのメモ、
/[{]/,/[}]/
は範囲式です。最初のパターンに一致するものが見つかるまでスキャンすることを意味します(/[{]/)
そして、2番目のパターンが見つかるまでスキャンします(/[}]/)
次に、sedコードの{}の間にあるアクションを実行します。この場合、 'p'とデバッグコード。 (ここでは説明しません。使用、変更、または削除してください)。コードが実際に{、}で区切られたブロックと一致していることを確認したら、/ [}]/a \ブロック終了デバッグを削除できます。
このコードサンプルは、中括弧のペア内にないものはすべてスキップします。上記の他の人が指摘したように、文字列や正規表現などに余分な{、}が埋め込まれていると、混乱しやすくなりますOR右中括弧が同じ行の場合、( fred.bearに感謝)
これがお役に立てば幸いです。
Pcregrepには-M(複数行)オプションを使用できます。
pcregrep -M '\{(\s*.*\s*)*\}' test.txt
\ sは空白(改行を含む)であるため、これは0個以上の(空白に続いて。*に続いて空白)と一致し、すべて中かっこで囲まれます。
更新:
これは貪欲でないマッチングを行うはずです:
pcregrep -n -M '\{(\n*.*?\n*)*?\}' test.txt
parser.awk:
#!/usr/bin/awk -f
function die(msg) { print msg > "/dev/stderr"; exit 1 }
BEGIN {
FS=opener
if (mode=="l") linewise=1
else if (mode=="i") trim_closer=length(closer)
else if (mode!="a") die("mode must be one of: l,i,a")
}
{
live=level
for (f=1; f<=NF; f++) {
if (f>1) {
live=++level
if (mode=="i" && level>1 || mode=="a") printf "%s", opener
}
cur=$f
level-=gsub(closer, "", cur)
if (level<0) die("Unbalanced")
if (!linewise) {
cur=$f
if (sub(".*" closer, "", cur)) printf "%s",
substr($f, 1, length($f) - length(cur) - (level ? 0 : trim_closer))
else if (live) printf "%s", $f
}
}
if (live) {
if (linewise) print
else print ""
}
}
END { if (level>0) die("Unbalanced") }
awk -v'opener={' -v'closer=}' -v'mode=a' -f parser.awk
として呼び出します。 modeがa
の場合、すべての最も外側のバランスのとれた{...}
の括弧と内容を出力します。モードがi
の場合、その内容のみを出力します。モードがl
の場合、最も外側の{...}
が始まる、開いている、または閉じるところに完全な行を出力します。
XMLのような表現(無限に再帰的なタグ)は「通常の言語」ではないため、正規表現(regex)で解析することはできません。理由は次のとおりです。
https://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags/
http://www.perlmonks.org/?node_id=66835
https://stackoverflow.com/questions/1379524/textual-protocol-which-is-not-a-regular-language
正規表現は、一致するネストされた括弧を見つけることができません。
検索する括弧内にネストされた括弧のペアがないことが確実な場合は、最初の閉じ括弧まで検索できます。例えば:
sed -r 's#\{([^}])\}#\1#'
これにより、「{」から「}」までのすべてのテキストがそれらの間のテキストに置き換えられます。