重要なお知らせ

「教えて! goo」は2025年9月17日(水)をもちまして、サービスを終了いたします。詳細はこちら>

電子書籍の厳選無料作品が豊富!

$str = "hello/$(hoge/$(hoge/good)/id)/namae";
このような文字列を/で以下のように分割して配列に入れようと考えています。
Array
(
[0] => hello
[1] => $(hoge/$(hoge/good)/id)
[2] => namae
)
しかし単にsplitで分割してもこのようにならないので正規表現でやりたいんですがどのようにしたらこのように分割できるでしょうか??

A 回答 (6件)

だいたいやりたいことが判りました。


ANo.5さんのと余り変わりませんが、サンプルです。
preg_replace_callbackを使っています。

function _get($path) {
$ret = rand(1000, 9999);
echo "path: $path[1] -> $ret\n";
return $ret;
}

function _kaiseki($str) {
do {
echo "str: $str\n";
$str = preg_replace_callback('|\$\(([^()\$]+)\)|', '_get', $str, -1, $cnt);
} while ($cnt > 0);
return $str;
}

$str = '$(DATA_ATR/$(DATA_ATR/$(DATA/hoge)/id)/NO)';
echo 'result: '. _kaiseki($str). "\n";
    • good
    • 0
この回答へのお礼

こういったやりかたもあるんですね。
ちょっと調べてみたいと思います。
何度もご回答していただきありがとうございます。

お礼日時:2006/11/25 13:39

こんな感じでできないでしょうか?



###文字列を解析する関数
function _kaiseki($str){
$pattern = '/(^.*)(\$\([^\(\)]*\))(.*$)/';
for ($i = 0 ;;++$i) {
//echo $str . "<br />";
preg_match($pattern,$str,$tmp);
$replace_str = _get($tmp[2]);
$replacement = '${1}' . $replace_str . '${3}';
$str = preg_replace($pattern,$replacement,$str);
if (preg_match($pattern, $str) == "") break;
}
return $str;
}
    • good
    • 0
この回答へのお礼

回答ありがとうございます。
これを参考に自分なりに修正してみたいと思います。

お礼日時:2006/11/25 13:36

補足を拝見しましたが、いまいちよく判りませんでした。

。。
直接的な回答ではありませんが、以下のような方法でプログラムからデータを取扱いしやすくする方法もあります。参考まで。

// '$(aaa/$(bbb/$(aaa/ccc)/id)/NO)' を以下に置換
// → 'array("aaa",array("bbb",array("aaa","ccc"),"id"),"NO")'
// これをevalして、$hogeに代入します。

$str = '$(aaa/$(bbb/$(aaa/ccc)/id)/NO)';
$str = preg_replace(array('/\\b/', '/\\$/', '/\\//'), array('"', 'array', ','), $str);
echo $str. "\n";
eval("\$hoge=$str;");
var_dump($hoge);

evalを使うので、セキュリティ的な問題が無いように注意が必要ですが。

この回答への補足

もう少し補足します。全体的にはこんな流れになります。
$str="$(DATA_ATR/$(DATA_ATR/$(DATA/hoge)/id)/NO)";
echo _kaiseki($str);
###データを置換する関数
function _get($path){
if(preg_match('/^DATA/', $path)){
/*長いのでここは省略します。
解析したパスを渡してデータを取得する関数です。
(例えばidなどを取得します)
*/
}else if(preg_match('/^DATA_ATR/', $path)){
/*ここも長いので省略します。処理は上と同じ*/
}
return $result;
}
###文字列を解析する関数
function _kaiseki($str){
if(preg_match('/^\$/', $str)){
$str = preg_replace('/^\$/', "", $str);
if(preg_match('/^\(([^$()]*)\)$/', $str, $tmp)){
$data = _get($tmp[1]); }else{
/*ここを通るときはこうなってます。

(1)DATA_ATR/$(DATA_ATR/$(DATA/hoge)/id)/NO
処理の流れはまず$(DATA/hoge)を_get()に渡してデータを得ます。
データを得るとこんな感じになるはずです。1111は取得したデータ。
(2)DATA_ATR/$(DATA_ATR/11111/id)/NO
次に$(DATA_ATR/11111/id)のデータを取得します。
また_get()を呼んで処理を行いデータを得ます。そうすると
(3)DATA_ATR/12345/NO になるはずです。
最後にもう一度_get()を呼んで欲しかったデータを取得します。
*/
}
}
return $data;
}
悩んでいるのはこのパスの解析の部分です。よろしくお願いします。

補足日時:2006/11/25 05:03
    • good
    • 0

No.1です。


外してるかもしれませんが、こういうことでしょうか?
whileでpreg_replace()をまわしてます。
(コメントアウトしているechoの//をはずせば途中経過が表示されます)

$str="$(aaa/$(bbb/$(aaa/ccc)/id)/NO)";
$replace_str = Array("111","12345");
$pattern = '/(^.*)(\$\([^\(\)]*\))(.*$)/';
for ($i = 0 ;; ++$i) {
//echo $str . "<br />";
$replacement = '${1}' . $replace_str[$i] . '${3}';
$str = preg_replace($pattern,$replacement,$str);
if (preg_match($pattern, preg_replace($pattern,$replacement,$str)) == "") break;
}
echo $str;
    • good
    • 0

$(xxx/yy/zzzzz)/aaa/$(bbb/$($(cc/ddd)/eee/fff)/ggg)


のような文字列にも対処できるような汎用的なものにしたいんでしょうか? なおかつ、$()によるネストの回数に制限が無いとしたら、正規表現では太刀打ちできないと思います。

形式が決まっているのであれば、ANo1さんの方法などでできると思います。

この回答への補足

少し補足させてください。
実際に実装したいと考えているのは以下のような処理です。
$str=$(aaa/$(bbb/$(aaa/ccc)/id)/NO)
$(aaa/ccc)のとき特定の数字(例えば111)を取得して
$(aaa/$(bbb/111/id)/NO)
となり、今度は$(bbb/111/id)のとき特定の数字(例えば12345)を取得します。
そして最後に$(aaa/12345/NO)となってこの文字列が指すあるデータを取得するという処理の流れになります。
このような処理をやりたいと考えていてこの文字列の解析に悩んでいるんです。

補足日時:2006/11/24 18:54
    • good
    • 0

$str = "hello/$(hoge/$(hoge/good)/id)/namae";


$replacement = '$1,$3,$5';
$pattern= '/(^[^\/]*)(\/)(\$.*)(\/)([^\/].*$)/';
$s = split(",",preg_replace($pattern,$replacement,$str));

でいけると思います。ただし、$strに","が入っていると誤動作します。
    • good
    • 0
この回答へのお礼

ありがとうございます。参考にしてみます。

お礼日時:2006/11/24 18:00

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!