20

CSSファイルを解析し、すべてのCSSセレクターの前に別のCSSセレクターを追加したいと思います。

から:

p{margin:0 0 10px;}
.lead{margin-bottom:20px;font-size:21px;font-weight:200;line-height:30px;}

私は…したい:

.mySelector p{margin:0 0 10px;}
.mySelector .lead{margin-bottom:20px;font-size:21px;font-weight:200;line-height:30px;}

しかし、私のCSSファイルは本当に複雑なので(実際にはブートストラップCSSファイルです)、正規表現はすべてのCSSセレクターと一致する必要があります。

今のところ、私はこの正規表現を持っています:

([^\r\n,{};]+)(,|{)

結果はhttp://regexr.com?328psで確認できますが、ご覧のとおり、一致してはならない一致がたくさんあります。

例えば:

text-shadow:0 -1px 0 rgba(0,

正に一致しますが、すべきではありません

誰かが解決策を持っていますか?

4

10 に答える 10

30

ありません。CSSセレクターは「正規言語」の例ではないため、正規表現で解析することはできません。CSS文法仕様に基づいて独自のパーサーを構築する必要があります:http ://www.w3.org/TR/css3-syntax/#detailed-grammar

CSSはLL(1)文法として記述されているため、Yaccなどのツールを使用してパーサーを生成することをお勧めします。

于 2012-09-25T03:36:41.210 に答える
26

だから私はついに私の要件に合った正規表現を見つけました

([^\r\n,{}]+)(,(?=[^}]*{)|\s*{)

重要なポイントは、悪い一致を避けるためにポジティブルックアヘッドを追加することでした

(?=[^}]*{)

ここで結果を見ることができます:http: //regexr.com? 328s7

私が推奨できる唯一の予防策は、すべてのブロックコメントを削除することです。

于 2012-09-25T07:36:56.047 に答える
6

だからついに私はそれを行うためのより良い方法を見つけました。

LESSエディターを使用しています(例:http://lesstester.com/

そして、単純に私のcssファイル全体をネストします:.mySelector {your css here}

于 2013-11-18T04:58:06.960 に答える
3

確かに、正規表現を使用してcssセレクターを選択することはできませんが、正規表現を使用してcssルールを選択できるため、逆の方法でジョブを実行できます。

  1. 同じ行にセレクターとルールがないように、cssファイルをフォーマットします。コードは次のようになります。

    p {
    margin:0 0 10px;
    }
    .lead {
    margin-bottom:20px;
    font-size:21px;
    font-weight:200;
    行-高さ:30px;
    }

  2. すべてのルールを選択します(正規表現:(^(。)*;)

    p {
    margin:0 0 10px;
    }
    .lead {
    margin-bottom:20px;
    font-size:21px;
    font-weight:200;
    行-高さ:30px;

    }

  3. ルールにプレフィックスを追加します(例####)

    p {
    #### margin:0 0 10px;
    }
    .lead {
    #### margin-bottom:20px;
    #### font-size:21px;
    #### font-weight:200;
    #### line-height:30px;

    }

  4. ####で始まらない、行に戻る、}ではないすべての行を選択します(正規表現:^ [^ #### \ n}])

    p {
    #### margin:0 0 10px;
    }
    .lead {
    #### margin-bottom:20px;
    #### font-size:21px;
    #### font-weight:200;
    #### line-height:30px;
    }

  5. cssプレフィックスを追加します

    .my_class_prefix p {
    #### margin:0 0 10px;
    }
    .my_class_prefix .lead {
    #### margin-bottom:20px;
    #### font-size:21px;
    #### font-weight:200;
    #### line-height:30px;
    }

  6. 追加されたプレフィックスを削除します####

    .my_class_prefix p {
    margin:0 0 10px;
    }
    .my_class_prefix .lead {
    margin-bottom:20px;
    font-size:21px;
    font-weight:200;
    行-高さ:30px;
    }

于 2014-09-16T15:13:23.650 に答える
2

シンプルで読みやすい正規表現は次のとおりです。

[\#\.\w\-\,\s\n\r\t:]+(?=\s*\{)

このツールのcssコードでテストできます`

于 2014-08-28T15:12:27.030 に答える
1

同様の問題に直面し、以下を使用して、コメントやメディアクエリなしでCSSセレクターとディレクティブのみを抽出しました。

/^(?!.*@media)[\t ]*([a-zA-Z#.:*\[][^{\/]*\s*){[\s\S]*?}/

例:https ://regex101.com/r/JmjthP/5

いくつかのエッジケースが欠けていると確信していますが、私にとってはうまくいっているようです。

この質問を参照してください:RubyRegExp-すべてのCSSセレクターとディレクティブに一致します

于 2018-09-26T15:40:37.960 に答える
1

これは私が思いついたものです:

(?<=\s)[^ ]*\s*\{[^\}]+\:[^\}]+\}

于 2020-10-04T20:04:14.903 に答える
0

これが私が同様の問題に使用した解決策です。で始まるすべてのcssルールを削除したかったの@です。このために、次の正規表現を使用しました。

@\s*.*\s*\{((?!\n\})[\s\S])+\n\}

これは、ルールが新しい行で終了することを前提としています。そうすれば、ネストされたcssルールを処理できます。

于 2016-12-02T13:06:29.743 に答える
0

有効なCSSセレクターに一致する単一の正規表現を作成することはできませんが、いくつかの正規表現と少しのロジックを組み合わせて、目標を達成することができます。

以下では、Nodeのfsモジュールを使用してCSSを読み取りますが、必要に応じて生のCSS文字列を取得できます。

const fs = require('fs'),
    myClassName = 'mySelector',
    mySelector = '.' + myClassName,
    mySelectorRegex = new RegExp(`\\.${myClassName}([ .#[:(]|$)`),
    cssSelectorRegex = /[@.#a-zA-Z][^}]*?(?={)/g;

let css = fs.readFileSync('path/to/file.css').toString();

css = css.replace(cssSelectorRegex, match => {

    // Match is a string of selectors like '.foo' or '.foo, #bar'
    // We need to split it on the comma and handle each selector individually
    return match.split(',').map(selector => {

        selector = selector.trim();

        // Don't alter media queries, imports, or selectors that already contain '.mySelector'
        if (selector.startsWith('@') || selector.match(mySelectorRegex)) {

            return selector;

        }

        // Prepend '.mySelector ' to the selector
        return mySelector + ' ' + selector;

    // Combine the list of selectors back together
    }).join(',');

});
于 2018-10-09T18:27:59.697 に答える
0

興味深い議論-純粋な正規表現ではなく、本当に短いJS関数:

function cssNester(css, nestWith) {
  let kframes = [];
  css = css.replace(/@(-moz-|-webkit-|-ms-)*keyframes\s(.*?){([0-9%a-zA-Z,\s.]*{(.*?)})*[\s\n]*}/g, x => kframes.push(x) && '__keyframes__');
  css = css.replace(/([^\r\n,{}]+)(,(?=[^}]*{)|\s*{)/g, x => x.trim()[0] === '@' ? x : x.replace(/(\s*)/, '$1' + nestWith + ' '));
  return '/*' + nestWith + '*/\n' + css.replace(/__keyframes__/g, x => kframes.shift());
}
于 2021-05-13T10:39:46.710 に答える