0

preg_replace()配列の使用に問題があります。

基本的に、この文字列を転置したいと思います。

$string = "Dm F Bb F Am";

$New_string = "F#m D D A C#m";

これが私がすることです:

$Find = Array("/Dm/", "/F/", "/Bb/", "/Am/", "/Bbm/", "/A/", "/C/");
$Replace = Array('F#m', 'A', 'D', 'C#m', 'Dm', 'C#', 'E');
$New_string = preg_replace($Find, $Replace, $string);

しかし、代わりに次の結果が得られます。

E##m E# で E#m

問題は、すべての一致が次のように置き換えられることです。このようなことが起こります (E##m の例):

Dm -> F#m -> A#m -> C##m -> E##m

「Dm」を「F#m」、「F」を「A」などに単純に変更する解決策はありますか?

ありがとうございました !

4

2 に答える 2

4

strtr()を使用できます:

<?php
    $string = "Dm F Bb F Am";
    $Find = Array('Dm', 'F', 'Bb', 'Am', 'Bbm', 'A', 'C');
    $Replace = Array('F#m', 'A', 'D', 'C#m', 'Dm', 'C#', 'E');

    $New_string = strtr($string, array_combine($Find, $Replace));

    echo $New_string;

    // F#m A D A C#m
于 2012-09-12T10:39:42.043 に答える
1

preg_replace_callback()おそらくこれを行う最も簡単な方法です。1 回の操作で行う必要があります。このようなもの:

<?php

$string = "Dm F Bb F Am";

$replacements = array (
    'Dm' => 'F#m',
    'F' => 'A',
    'Bb' => 'D',
    'Am' => 'C#m',
    'Bbm' => 'Dm',
    'A' => 'C#',
    'C' => 'E'
);

$New_string = preg_replace_callback('/\b('.implode('|', array_map('preg_quote', array_keys($replacements), array_fill(0, count($replacements), '/'))).')\b/', function($match) use($replacements) {
    return $replacements[$match[1]];
}, $string);

echo $New_string;

動いているのを見る

さて、上記のコードが少しわかりにくいことはわかっているので、少し分解して、個々のコンポーネントが何をするかを見てみましょう。

// The input string and a map of search => replace
$string = "Dm F Bb F Am";
$replacements = array (
    'Dm' => 'F#m',
    'F' => 'A',
    'Bb' => 'D',
    'Am' => 'C#m',
    'Bbm' => 'Dm',
    'A' => 'C#',
    'C' => 'E'
);

// Get a list of the search strings only
$searches = array_keys($replacements);

// Fill an array with / characters to the same length as the number of search
// strings. This is required for preg_quote() to work properly
$delims = array_fill(0, count($searches), '/');

// Apply preg_quote() to each search string so it is safe to use in the regex
$quotedSearches = array_map('preg_quote', $searches, $delims);

// Build the regex
$expr = '/\b('.implode('|', $quotedSearches).')\b/';

// Define a callback that will translate search matches to replacements
$callback = function($match) use($replacements) {
  return $replacements[$match[1]];
};

// Do the replacement
$New_string = preg_replace_callback($expr, $callback, $string);
于 2012-09-12T10:40:10.947 に答える