2

何百 (700 以上) の Web フォルダーのセットがあり、それぞれに個別の CSS スタイルシートが含まれています。(興味のある方は、オンラインコースです。)

最近、リンクに下線を付けることが決定されました。W3Cがずっと前にそれを決定したことは知っていますが、これは大学であり、彼らは物事を再決定するのが好きです.

正規表現の検索と置換を使用して、すべての CSS ファイルを更新しようとしています。

これまでの主なハードルは次のとおりです。

  • ウィンドウズ。私はそれが好きではありません、私はそれを使用していません。FART のようなコマンド ライン ユーティリティは、単一行の処理には最適ですが、よりカスタマイズされた強力な検索を作成するには多すぎることがわかりました。
  • マルチライン。CSS ファイルは通常、次のような構造になっています。

    a, .surveypopup{
    text-decoration:none;
        cursor:pointer;
    }
    

    つまり、セレクター ("{" の前の部分) は常にグッズとは別の行にあります。イベント (:hover など) なしで「a」を変更するすべてのセレクターに一致させ、「text-decoration:none」を含むものはすべて「text-decoration:underline」になるようにし、挟まれる可能性のある他のスタイリング コードを台無しにしたくありません。の間に。

  • 大文字小文字を区別しません。RegEx の場合、これは問題になりません。この CSS の作成者は、大文字の使用に関して工夫を凝らしているかもしれませんし、そうでないかもしれません。

現在エラーが発生しているコマンドラインは次のとおりです。

find . -iname "*.css" | xargs sed -i "" "s|\(\ba\(,\|\.\|\s\|\b\)\[^\{\]\*\{\[^\}\]\*\)text-decoration\:none|a.\1text-decoration:underline;|g"

生成するもの:

sed: 1: "s|\(\ba\(,\|\.\|\s\|\b\ ...": RE error: invalid repetition count(s)

私のニーズがbashスクリプトを書くことを正当化するかどうか疑問に思っていますか? 変更が必要な場合は、各ファイルのバックアップを作成すると便利です。そのような複数の操作は、スクリプトで簡単になります...

いずれにせよ、sed で何をエスケープし、何をエスケープしないかがわからないため、問題が発生していると思います。

助けてください!

4

2 に答える 2

6

ファイル全体を一度に操作するには、次を使用できます。

s/(\ba(?=(?:\.|,|\s|{|#)))([^}{]*?{[^}]*?text-decoration:\s*)none(\s?!important)?;/$1$2underline;/g

より適切にフォーマットされた、これは次のとおりです。

s/                          # find and replace
    (                       # group 1
        \b                  # a word boundary
        a                   # followed by 'a'
        (?=                 # where the next character (positive lookahead)
            (?:             # (inside a non-capturing group)
              \.|,|\s|{|#   # is one of '.', ',', '{', '#' or whitespace
            ) 
        )
    )
    (                       # group 2
        [^}{]*?             # then non-greedily match anything up to a '{' or '}'
                            # if '}' is found, the next character will not match
                            # and therefore the whole regex will not match
        {                   # and find the '{'
        [^}]*?              # and then non-greedily match anything until we 
                            # find 'text-decoration', but don't keep matching
                            # when a '}' is found
        text-decoration:    # then find 'text-decoration'
        \s*                 # and optional whitespace
    )
    none                    # and 'none'
    (\s?!important)?        # and optional '!important'
    ;                       # and a ';'
/
    $1                      # replace by group 1
    $2                      # then group 2
    underline;              # then 'underline;'
/g

サンプルファイル:

$ cat test.css
a { text-decoration: none; }
b, a { text-decoration: none; }
b, a, u { text-decoration: none; }
b, a.cat, u { text-decoration: none; }
b, a.cat, u { text-decoration: none !important; }
b, a, u {
    text-decoration: none;
}
b, a, u {
    color: red;
    text-decoration: none;
}
b, a, u {
    color: red;
    text-decoration: none;
    padding: 10px;
}

そして結果:

perl -0777 -p -e 's/(\ba(?=(?:\.|,|\s|{|#)))([^}{]*?{[^}]*?text-decoration:\s*)none(\s?!important)?;/$1$2underline;/g' test.css
a { text-decoration: underline; }
b, a { text-decoration: underline; }
b, a, u { text-decoration: underline; }
b, a.cat, u { text-decoration: underline; }
b, a.cat, u { text-decoration: underline; }
b, a, u {
    text-decoration: underline;
}
b, a, u {
    color: red;
    text-decoration: underline;
}
b, a, u {
    color: red;
    text-decoration: underline;
    padding: 10px;
}

perl の-iフラグを使用して (バックアップ拡張子を設定することを忘れないでください!)、その場でファイルを操作できます。

a;を含むことができる他の多くの可能な CSS ルールがあることは明らかです。例:html>aまたはdiv a b; この正規表現は最初のものを見つけられず、2番目のものを見つけますが、どちらの場合も「間違っています」。基本的に、これらのタイプのタスクに正規表現を使用できるのは、操作しているテキストについて強い仮定を立てることができる場合のみです。

}一致を避けるためにルールの一部に追加された更新。例:

b { background-image: url('http://domain.com/this is a picture.jpg'); }
u { text-decoration: none; }
于 2012-05-16T16:42:22.567 に答える
4

CSS の解析に RegEx を使用しないでください。代わりに CSS パーサーを使用してください。トラブルの世界を救うことができます。

于 2012-05-16T16:59:54.130 に答える