PHPでの対象文字列の分割について質問です。


文章を分割したいのですがうまくいきません。
分割対象にはマルチバイト文字やシングルバイト文字が混在していてます。
一例ですが以下のような感じです。

$sample = "今日はいい天気ですね。\n明日も<code>http://q.hatena.ne.jp/index.php?sample=sample&test=test</code>晴れるといいですね。\nでも明日はマラソン大会なので/hogehogesample/雨だと<code>とても</code>嬉しいです。";

この例で言うと<code>で囲まれた部分とそうでない部分に分けることが出来ればと考えております。
substrで取り出すためにstropsで出現位置を特定しようとしているのですがうまくいきません。
現在は
1.strposで<code>と</code>の位置を特定
2.「1」での値を元にsubstrで分割
としているのですが途中のシングルバイト文字でズレたりするようでうまくいきません。
mb_substrを使ってもマルチバイトとシングルバイトの文字の混合だとどうしても綺麗に分割はしてくれないようです。

こういった混在している文字でうまく分割をする際の手順や流れなどあればご教示いただけないでしょうか。

回答の条件
  • 1人2回まで
  • 登録:
  • 終了:2011/05/18 07:56:49
※ 有料アンケート・ポイント付き質問機能は2023年2月28日に終了しました。

回答1件)

id:HowAreYou No.1

回答回数91ベストアンサー獲得回数17

ポイント60pt

preg_split で分割してこんな感じ。

<?php
$sample = "今日はいい天気ですね。\n明日も<code>
http://q.hatena.ne.jp/index.php?sample=sample&test=test</code>晴れるといいですね。\nでも明日はマラソン大会なので/hogehogesample/雨だと<code>とても</code>嬉しいです。" ;

$s = preg_split('!</?code>!', $sample) ;
for ($i = 0, $s0 = $s1 = array(); $i < count($s); ++$i) {
  if ($i % 2) $s1[] = $s[$i] ;
  else $s0[] = $s[$i] ;
}

print_r($s0) ;
print_r($s1) ;

出力例

Array
(
    [0] => 今日はいい天気ですね。
明日も
    [1] => 晴れるといいですね。
でも明日はマラソン大会なので/hogehogesample/雨だと
    [2] => 嬉しいです。
)
Array
(
    [0] => 
http://q.hatena.ne.jp/index.php?sample=sample&test=test
    [1] => とても
)

おまけ

for 文は 1行でも書ける。みにくいのでお勧めはしません。

<?php

$sample = "今日はいい天気ですね。\n明日も<code>
http://q.hatena.ne.jp/index.php?sample=sample&test=test</code>晴れるといいですね。\nでも明日はマラソン大会なので/hogehogesample/雨だと<code>とても</code>嬉しいです。" ;

$s = preg_split('!</?code>!', $sample) ;
for ($i = 0, $s0 = $s1 = array(); $s[$i] && ${'s'.($i % 2)}[] = $s[$i]; ++$i) ;

print_r($s0) ;
print_r($s1) ;
id:quocard

回答ありがとうございます。

文字単位での分割ではなく、目印となるもので分割していけばいいですね。

出来るだけ細かくしようとして色々と変なことになってました。

参考にさせていただきます。

2011/05/16 10:28:31
  • id:asuka645
    こういうときには正規表現を使います。
    スクリプトはUTF-8で保存してください。
    ----
    <?php
    $sample = "今日はいい天気ですね。\n明日も<code>http://q.hatena.ne.jp/index.php?sample=sample&test=test</code>晴れるといいですね。\nでも明日はマラソン大会なので/hogehogesample/雨だと<code>とても</code>嬉しいです。";
    $pat = "/<code>(.*?)<\/code>/usm";
    preg_match_all($pat, $sample, $ar, PREG_PATTERN_ORDER);
    var_dump($arr);
    ?>
    ----
    $ar[1][0]と$ar[1][1]に目的の部分文字列が切り出されます。
  • id:Lhankor_Mhy
    回答拒否されているようですので、コメント欄に。
     
    <?php
    $sample = "今日はいい天気ですね。\n明日も<code>
    http://q.hatena.ne.jp/index.php?sample=sample&test=test</code>晴れるといいですね。\nでも明日はマラソン大会なので/hogehogesample/雨だと<code>とても</code>嬉しいです。";
    $notCode = '';
    $code ='';
    foreach (explode('</code>',$sample) as $str) {
    $splitStr = explode('<code>',$str) ;
    $notCode .= $splitStr[0];
    $code .= isset($splitStr[1]) ? $splitStr[1] : '';
    }
    echo $notCode;
    echo $code;
    ?>
  • id:quocard
    回答ありがとうございます。
    難しく考えていたようで、基準となる部分は決まっているのでそこを起点に検索・分割してやればいいだけでしたね。
    とは言え非常に参考になりました。

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

回答リクエストを送信したユーザーはいません