Jadi saya mencoba membuat encoder/decoder kode morse; Saya menyelesaikan pembuat enkode, tetapi dekoder memberi saya beberapa masalah.

Jadi, jika saya menggunakan fungsi test dan memasukkan "ab" itu akan mengembalikan "ab". Namun, jika saya memasukkan "a b" ia mengembalikan "c d" (sebagaimana seharusnya, 100% berfungsi)

function test($code){
    $search = array('/\ba\b/', '/\bb\b/');
    $replace = array('c', 'd');
    return preg_replace($search, $replace, $code);
}

TAPI ketika saya menggunakan fungsi morsedecode dan memasukkan ".- -..." itu tidak melakukan apa-apa dan mengembalikan ".- -...".

function morsedecode($code){
    $search = array('/\b.-\b/', '/\b-...\b/');
    $replace = array('a', 'b');
    return preg_replace($search, $replace, $code);
}

Saya terjebak karena tampaknya tidak berfungsi untuk simbol, seperti halnya untuk huruf dan kata. Adakah yang tahu alasannya dan apakah ada cara untuk mengatasi ini di PHP?

0
Crimin4L 23 Desember 2020, 06:39

3 jawaban

Jawaban Terbaik

Perbarui

Jika semua karakter Anda dikelilingi oleh spasi (atau awal/akhir baris), Anda mungkin akan lebih mudah menggunakan strtr daripada pendekatan berbasis regex. Karena strtr menggantikan kecocokan terlama terlebih dahulu, Anda tidak perlu khawatir tentang (misalnya) -.- (k) sebagian diganti sebagai -a.

function morsedecode($code){
    $search = array('.-', '-...');
    $replace = array('a', 'b');
    return strtr($code, array_combine($search, $replace));
}

echo morsedecode(".- -...");

Keluaran:

a b

Demo di 3v4l.org

Jawaban Asli

Masalah Anda adalah \b cocok dengan batas kata yaitu tempat karakter di sebelah kiri adalah karakter kata (a-zA-Z0-9_) dan karakter di sebelah kanan bukan karakter kata (atau sebaliknya). Karena Anda tidak memiliki karakter kata dalam string input Anda, Anda tidak akan pernah bisa mencocokkan batas kata. Sebagai gantinya, Anda bisa menggunakan pencarian untuk karakter yang bukan titik atau tanda hubung:

function morsedecode($code){
    $search = array('/(?<![.-])\.-(?![.-])/', '/(?<![.-])-\.\.\.(?![.-])/');
    $replace = array('a', 'b');
    return preg_replace($search, $replace, $code);
}

echo morsedecode(".- -...");

Keluaran

a b

Demo di 3v4l.org

Perhatikan bahwa . adalah karakter khusus dalam regex (cocok dengan karakter apa pun) dan perlu di-escape, jika tidak maka akan cocok dengan - serta ..

2
Nick 23 Desember 2020, 04:16

\b adalah batas kata, yang merupakan salah satu dari berikut ini.

  1. Sebelum karakter pertama dalam string, jika karakter pertama adalah karakter kata.
  2. Setelah karakter terakhir dalam string, jika karakter terakhir adalah karakter kata.
  3. Antara dua karakter dalam string, di mana satu adalah karakter kata dan yang lainnya bukan karakter kata.

'/\b.-\b/' Yang pertama \b tidak cocok di .- -... karena #1. Khususnya if the first character is a word character

Karakter kata = ASCII letter, digit or underscore jadi . bukan karakter kata.

Selain itu, Anda harus keluar dari karakter . seperti \..

Coba cari \s* (sejumlah spasi putih) alih-alih batas kata.

function morsedecode($code){
    $search = array('/\s*\.-\s*/', '/\s*-\.\.\.\s*/');
    $replace = array('a', 'b');
    return preg_replace($search, $replace, $code);
}

Contoh https://regex101.com/r/LCZXCn/1

1
bassxzero 23 Desember 2020, 03:54

Saya akhirnya menemukan perbaikan kecil saya sendiri untuk masalah ini:

    function morsedecode($code){
        $bd_code = str_replace(array('.', '-', '/'), array('dot', 'dash', '~slash~'), $code);
        $search = array('/\bdotdash\b/', '/\bdashdotdotdot\b/', '/\bdashdotdashdot\b/', 'etc..');
        $replace = array('a', 'b', 'c', 'etc..');
        $string =  preg_replace($search, $replace, $bd_code);
        return str_replace(array(' ', '~slash~'), array('', ' '), $string);
    }

Jelas bukan yang paling efisien tetapi menyelesaikan pekerjaan. @Nick answer jelas merupakan cara yang efisien.

1
Crimin4L 23 Desember 2020, 05:09