3

2つの代替形式でJavaScriptを使用して文字列を解析したいと思います。

id#state#{font name, font size, "text"}  
// e.g. button1#hover#{arial.ttf, 20, "Ok"}

また

id#state#text                            
// e.g. button1#hover#Ok

2番目のバリアントでは、デフォルトのフォントとサイズが想定されています。

さらに読む前に、私がフォーマットを制御していることを指摘する必要があるので、RegExpFriendly™である他のフォーマットについて聞いてみたいと思います。id#state#そうは言っても、 -partと同様に、歴史的な理由から2番目の選択肢が必要です。言い換えれば、柔軟性は{font name, font size, "text"}-partにあります。

さらに、可能な限り正規表現を使用したいと思います。はい、以下で提案するRegExpはかなり毛深いですが、私の場合、これは目前の問題に対する可能な解決策であるだけでなく、RegExp自体についてさらに学ぶことの問題でもあります。

3つまたは5つの情報要素を2つの形式でグループ化する現在の試みは次のとおりです。

var pat = /^(\w*)#(\w*)#
          (?:(?:\{([\w\.]*),\s*([0-9\.]*),\s*"([\w\s]*)"\})|([\w\s]*))$/;

var source1 = "button1#hover#{arial.ttf, 20, \"Ok\"}";
var source2 = "button1#hover#Ok";

var result1 = source1.match ( pat );
var result2 = source2.match ( pat );

alert ( "Source1: " + result1.length + " Source2: " + result2.length );

この式をhttp://www.regular-expressions.info/javascriptexample.htmlでテストしたところ、次のようになりました。

result1 = [ button1#hover#{arial.ttf, 20, "Ok"}, button1, hover, arial.ttf, 
            20, Ok, undefined ]

result2 = [ button1#hover#Ok, button1, hover, undefined, 
            undefined, undefined, Ok ]

これが私がRegExpを分解する方法です:

^(\w*)#(\w*)#(?:(?:\{([\w\.]*),\s*([0-9\.]*),\s*"([\w\s]*)"\})|([\w\s]*))$

^                 # anchor to beginning of string
(\w*)             # capture required id
#                 # match hash sign separator
(\w*)             # capture required state
#                 # match hash sign separator
                  # capture text structure with optional part:
(?:(?:\{([\w\.]*),\s*([0-9\.]*),\s*"([\w\s]*)"\})|([\w\s]*))  
$                 # anchor to end of string

テキスト構造のキャプチャは、最も危険な部分だと思います。私はそれを次のように分解します:

(?:                  # match all of what follows but don't capture
    (?:\{            # match left curly bracket but don't capture (non-capturing group)
          ([\w\.]*)  # capture font name (with possible punctuation in font file name)
          ,\s*       # match comma and zero or more whitespaces
          ([0-9\.]*) # capture font size (with possible decimal part)
          ,\s*"      # match comma, zero or more whitespaces, and a quotation char
          ([\w\s]*)  # capture text including whitespaces
    "\})             # match quotation char and right curly bracket (and close non-capturing group)
    |                # alternation operator
    ([\w\s]*)        # capture optional group to match the second format variant
)                    # close outer non-capturing group

私の質問は2つあります:

1)result1の場合、末尾の未定義の一致を回避するにはどうすればよいですか?

2)result2の場合の途中で3つの未定義の一致を回避するにはどうすればよいですか?

ボーナス質問:

私は故障を正しく理解しましたか?(RegExpが完全に期待どおりに機能していないため、何か問題があると思います。)

ありがとう!:)

4

1 に答える 1

2

正規表現のグループには、演算子(特に|演算子)に関係なく、左から右に番号が付けられます。取得する(x)|(y)と、「x」または「y」のグループはになりますundefined

したがって、結果の空のスロットを回避することはできません。実際、私はあなたがそれらを望んでいると思います。そうでなければ、どの形式の入力に一致したかが本当にわからないからです。

于 2013-01-16T13:59:04.820 に答える