2

正規表現で取り除こうとしてきた余分な綿毛を含む、Google sketchup からエクスポートされた一連の座標があります。たとえば、SketchUp から .xsi ファイルのキャンバスに 3D で図面をすばやく取得するのは非常に興味深いと思います。1 つの変数にデータ セットの複数のインスタンスがあります。

$str = 'SI_NurbsCurve Edge1 {
        1、
        0,
        0,
        4、
        0,0,1,1,
        2、
        870.243,1229.35,143.395,1
        927.537,1323.53,103.842,1
        }

        SI_NurbsCurve Edge2 {
        1、
        0,
        0,
        4、
        0,0,1,1,
        2、
        899.54,1217.88,116.255,1
        870.243,1229.35,143.395,1
        }';

この正規表現を使用して、座標データを除く複数のインスタンスからすべてを削除しようとしました:

$reg = '#SI_NurbsCurve エッジ[^"]* {
        1、
        0,
        0,
        4、
        0,0,1,1,
        2,#';  
$rep="";
$str=preg_replace($reg,$rep,$str);

ただし、この結果、文字列で見つかった最後の座標セットのみがエコーされます。この例では、次のものが残ります。

899.54,1217.88,116.255,1
870.243,1229.35,143.395,1

それに加えて、座標の各行で発生する最後の数字「1」を削除しようとしているため、この例全体は次のようになります。

870.243,1229.35,143.395,
927.537,1323.53,103.842,

899.54,1217.88,116.255,
870.243,1229.35,143.395,

私はあなたの時間とノウハウに非常に感謝しています!

4

3 に答える 3

0

$ str = substr($ str、0、-1)を探していると思います

于 2012-08-07T13:17:16.030 に答える
0

最初の問題 (最後の値のみを取得する) は、おそらくこれが原因です。

#SI_NurbsCurve Edge[^"]*

貪欲でない正規表現が必要になるか、後の値Edgeが単なる数値の場合:

#SI_NurbsCurve Edge[0-9]*

その後、残りのすべての行の最後の 2 文字を切り取ることができます。

おそらく、{文字もエスケープする必要があります。各セットの後にスペース/改行を\{考慮して}、最初の行は次のようにする必要があります。

$str = '#(\}\s+)?SI_NurbsCurve Edge[0-9]* \{

Codepadの実際の例 (各行の最後の 2 文字を除く...) を参照してください。

,1各行の終わりに残っているものも取り除くには、次のようにpreg_replace行を変更できます。

$str=preg_replace(array($reg, '#,1\r#'),array($rep,"\r"),$str);

これは少なくともCodepadでは機能しますが、おそらく改行のエンコーディングに依存します。

于 2012-08-07T13:20:55.390 に答える
0

決して完璧な解決策ではありませんが、利用可能なテスト データを使用すると、次のようにすると目的の出力が返されます。

$str = 'SI_NurbsCurve Edge1 {
        1,
        0,
        0,
        4,
        0,0,1,1,
        2,
        870.243,1229.35,143.395,1
        927.537,1323.53,103.842,1
        }

        SI_NurbsCurve Edge2 {
        1,
        0,
        0,
        4,
        0,0,1,1,
        2,
        899.54,1217.88,116.255,1
        870.243,1229.35,143.395,1
        }';

function stripExtra( $inElem ){
  return !preg_match( '/^(?:(?:[0124](?:,0,1,1)?\,)|(?:\})|(?:SI_NurbsCurve Edge.+ \{))$/' , $inElem );
}

$arr2 = array_filter( array_map( 'trim' , explode( "\n" , preg_replace( "/\,1\s+\n/" , ",\n" , $str ) ) ) , 'stripExtra' );

var_dump( $arr2 );

# Returns
# array(5) {
#   [7]=>
#   string(25) "870.243,1229.35,143.395,"
#   [8]=>
#   string(25) "927.537,1323.53,103.842,"
#   [10]=>
#   string(0) ""
#   [18]=>
#   string(24) "899.54,1217.88,116.255,"
#   [19]=>
#   string(25) "870.243,1229.35,143.395,"
# }

ソリューションをたどる...

function stripExtra( $inElem ){
  return !preg_match( '/^(?:(?:[0124](?:,0,1,1)?\,)|(?:\})|(?:SI_NurbsCurve Edge.+ \{))$/' , $inElem );
}

この関数は、提示された文字列と一致します。提供された文字列が特定のパターンに一致するかどうかに応じて、true または false が返されます。これにより、後の段階で不要な行を削除できます。ここで使用されるパターンは、次の行に一致します。

SI_NurbsCurve Edge1 {
0,
1,
2,
4,
0,0,1,1,
}

注: 1 つ以上のスペースが前に付いていない場合にのみ、これらの行に一致します。しかし、最終的な出力ではすべてのスペースが取り除かれているため、大したことではありません。

したがって、読みやすくするために、ここで 1 行の不思議を複数の行に置き換えて、より適切に説明できるようにします。

$arr2 = preg_replace( "/1\s+\n/" , "\n" , $str );

これにより、要求に応じて、行末の「,1」のインスタンスがコンマだけに置き換えられます。

$arr2 = explode( "\n" , $arr2 );

これにより、改行文字に基づいて文字列が分割され、各行が新しい要素を形成する配列が作成されます。

$arr2 = array_map( 'trim' , $arr2 );

これは、array_map()関数 ( PHP Documentationtrim() ) を使用して関数( PHP Documentation ) をそれぞれに適用し、各要素から先頭および/または末尾のスペースを削除します。

$arr2 = array_filter( $arr2 , 'stripExtra' );

上で書いた関数を覚えていますか? 次に、配列を移動し、各要素をテストします。上記の行と一致しない場合、それらは配列に保持されます。それらが上記の不要な行と一致する場合、その要素は配列から削除されます。

于 2012-08-07T13:50:58.167 に答える