5

私はこのような文字列の束を持っています:

a#aax1aay222b#bbx4bby555bbz6c#mmm1d#ara1e#abc

そして、私がする必要があるのは、次のような位置に基づいてそれらを分割することですhashtag:

Array
(
    [0] => A
    [1] => AAX1AAY222
    [2] => B
    [3] => BBX4BBY555BBZ6
    [4] => C
    [5] => MMM1
    [6] => D
    [7] => ARA1
    [8] => E
    [9] => ABC
)

したがって、ご覧のとおり、 のすぐ後ろの文字とhashtag、次の文字 + ハッシュタグの直前のハッシュタグの後のすべてがキャプチャされます。

各部分の最後に値がある場合にのみRegEx正常に機能する次のものがあります。numeric

正規表現のセットアップは次のとおりです。

preg_split('/([A-Z])+#/', $text, 0, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);

そして、それは次のようなものでうまく動作します:

C#mmm1D#ara1

しかし、これを変更すると(数字を削除して):

C#mmmD#ara

次に、それは結果になりますが、これは良くありません。

    Array
(
    [0] => C
    [1] => D
)

私はこの質問とこれも見ましたが、似ていますが、どれもうまくいきませんでした。

それで、私の質問は、数字が続く場合にのみ機能するのはなぜですか? どうすれば解決できますか?

ここで、私が持っているサンプル文字列のいくつかを見ることができます:

a#123b#abcc#def456         // A:123, B:ABC, C:DEF456
a#abc1def2efg3b#abcdefc#8  // A:ABC1DEF2EFG3, B:ABCDEF, C:8
a#abcdef123b#5c#xyz789     // A:ABCDEF123, B:5, C:XYZ789

PS 文字列は大文字と小文字を区別しません。

PPSこれらの文字列が一体何なのか考えたことがあるなら、それらはユーザーがアンケートに提出した回答であり、リファクタリングのようなことはできません。それらはすでに保存されており、続行する必要があるためです。

爆発を使用しないのはなぜですか?

私の例を見ると、# の直前の文字もキャプチャする必要があることがわかります。可能だと思われる場合はexplode()、出力も投稿してください。

アップデート

/([A-Z])+#/数値が含まれている場合にのみ機能する理由に焦点を当てる必要がありますか? ありがとう。

4

4 に答える 4

6

を使用する代わりに、代わりpreg_split()に一致させたいものを決定します。

  1. <any-char>#または のいずれかが続く場合の「単語」のセット<end-of-string>

  2. 文字 if の直後に#.

    $str = 'a#aax1aay222b#bbx4bby555bbz6c#mmm1d#ara1e#abc';
    
    preg_match_all('/\w+(?=.#|$)|\w(?=#)/', $str, $matches);
    

デモ

この式は、2 つの先読みアサーションを使用します。結果は にあり$matches[0]ます。

アップデート

それを別の方法で見ると、次のようになります。

preg_match_all('/(\w)#(\w+)(?=\w#|$)/', $str, $matches);

print_r(array_combine($matches[1], $matches[2]));

各エントリは 1 文字で始まり、その後にハッシュが続き、文字列の末尾または次のエントリの先頭に到達するまで X 文字が続きます。

出力は次のとおりです。

Array
(
    [a] => aax1aay222
    [b] => bbx4bby555bbz6
    [c] => mmm1
    [d] => ara1
    [e] => abc
)
于 2013-05-16T07:20:57.770 に答える
1

Regexpではなくexplode()を使用してください

$tmpArray = explode("#","a#aax1aay222b#bbx4bby555bbz6c#mmm1d#ara1e#abc");
$myArray = array();
for($i = 0; $i < count($tmpArray) - 1; $i++) {
    if (substr($tmpArray[$i],0,-1)) $myArray[] = substr($tmpArray[$i],0,-1);
    if (substr($tmpArray[$i],-1)) $myArray[] = substr($tmpArray[$i],-1);
}
if (count($tmpArray) && $tmpArray[count($tmpArray) - 1]) $myArray[] = $tmpArray[count($tmpArray) - 1];

編集:質問をよりよく読んだことを反映するように回答を更新しました

于 2013-05-16T07:15:21.000 に答える
0

explode()前の回答で述べたように、ハッシュ記号を除いて文字列を分割する関数を使用できます。

$myArray = explode("#",$string);

文字列 'a#aax1aay222b#bbx4bby555bbz6c#mmm1d#ara1e#abc' の場合、これは次のようなものを返します

$myarray = array('a', 'aax1aay22b', 'bbx4bby555bbz6c' ....);

ここで必要なのは、配列内の各文字列の最後の文字を別の項目として取得することだけです。

$copy = array();
foreach($myArray as $item){
  $beginning = substr($item,0,strlen($item)-1); // this takes all characters except the last one
  $ending = substr($item,-1); // this takes the last one
  $copy[] = $beginning;
  $copy[] = $ending;
} // end foreach

これは例であり、テストされていません。

編集

代わりにsubstr($item,0,strlen($item)-1);を使用できますsubstr($item,0,-1);

于 2013-05-16T07:21:50.463 に答える