Doğru regex ile karışık / latince ideografik tam metin sorgusu ayrıştırmak nasıl?

3 Cevap php

Ben karışık ideografik / latin (japanse / Korece / Çin) tam metin arama için regex kullanarak / formatlamasýný bazı girdileri çalışıyorum.

Ben yine (bu kodun orijinal yazara tam kredi) bulamıyorum hangi bir forumunda bir Asya / latin dili dize hijyen de kişinin girişimi eski örneği bulundu.

Ben, bu latin tabanlı sayılar 1,4-9 geri kalanından daha farklı sayılar 0, 2, ve 3 tedavi gibi görünüyor neden tam (temelde numaraları 0 davranır özellikle fonksiyonunun regex kısmını anlamakta sorun yaşıyorum onlar Asya karakterleri sanki 4-9 düzgün, ancak sayıları sorguda 0,2-3) tedavi edilir.

For example. I am trying to sanitize the following string:
"hello 1234567890 蓄積した abc123def"

and it will turn into:
"hello 1 456789 abc1 def 2 3 0 蓄 積 し た 2 3"

the correct output for this sanitized string should be:
"hello 1234567890 蓄 積 し た abc123def"

Eğer Asya karakterleri dışarı düzgün boşluk görebilirsiniz ama sayılar 0, 2, 3 farklı diğer tüm sayısından daha kabul edilir gibi. Regex bu numaraları 0,2 ve 3 tedavi neden herhangi bir yardım farklı bir büyük bir yardım olacaktır (ya da benzer bir sonuç elde daha iyi bir yol biliyorum!) Teşekkür ederim

Ben

dahil ettik


function prepareString($str) {
$str = mb_strtolower(trim(preg_replace('#[^\p{L}\p{Nd}\.]+#u', ' ', $str)));

return trim(preg_replace('#\s\s+#u', ' ', preg_replace('#([^\12544-\65519])#u', ' ', $str) . ' ' . implode(' ', preg_split('#([\12544-\65519\s])?#u', $str, -1, PREG_SPLIT_NO_EMPTY))));
}

UPDATE: Providing context for clarity

Ben Çin'de açılacak bir web sitesi yazma duyuyorum. Bu web sitesi bir arama fonksiyonu var ve ben arama sorgusu girişi için bir ayrıştırıcı yazmaya çalışıyorum.

Bir cümlede kelimeler arasında ayırıcı olarak "" kullanan İngilizce aksine, Çince kelimeler arasında boşluk yoktur. Bu nedenle, ben her Çince karakter ayırır ve ayrı ayrı veritabanı içinde her karakter için arayarak yeniden biçimlendirmek bir arama sorgusu var. Çinli kullanıcılar, aynı zamanda onların Çince karakterler (örn. Ivy 牛仔 铺) ile birlikte karıştırabilirsiniz gibi marka isimleri gibi şeyler için İngilizce / Latin karakterleri kullanacaktır.

Ne yapmak istiyorsunuz her bir boşlukla Çince karakter Çince karakter dışarı İngilizce kelimelerin tüm ayrı ve Ayrı olduğunu.

Bir arama sorgusu bu gibi görünebilir: Ivy 牛仔 铺

Ve ben bu gibi görünüyor böylece bunu ayrıştırmak isterim: Ivy 牛 仔 铺

3 Cevap

Alan'ın yorumların daha fazla araştırma ve yardım sonra ben mutluyum (Çince / Japonca) karakterleri lating ve ideografik ayırma için bir sorgu ayrıştırma işlevi elde etmek için doğru regex kombinasyonları bulmak mümkün:

function prepareString($str) {
    $str = mb_strtolower(trim(preg_replace('#[^\p{L}\p{Nd}]+#u', ' ', $str)));
    return trim(preg_replace('#\s\s+#u', ' ', preg_replace('#\p{Han}#u', ' ', $str) . ' ' . implode(' ', preg_split('#\P{Han}?#u', $str, -1, PREG_SPLIT_NO_EMPTY))));
}

$query = "米娜Mi-NaNa日系時尚館╭☆ 旅行 渡假風格 【A6402】korea拼接條紋口袋飛鼠棉"

echo prepareString($query); //"mi nana a6402 korea 米 娜 日 系 時 尚 館 旅 行 渡 假 風 格 拼 接 條 紋 口 袋 飛 鼠 棉"

Yasal Uyarı: ben Mandarin okuyamıyor ve dize üzerinde bir Çin web sitesinden kopyalanmıştır. Bu saldırı bir şey diyor, bana bildirin ve ben bunu kaldırın lütfen.

Sorun regex gibi görünüyor [^\12544-\65519]. Iki, beş basamaklı sekizlik kaçışları tarafından tanımlanan bir dizi olması gerekiyordu gibi görünüyor, ama bu şekilde çalışmıyor. Gerçek dökümü şöyle:

\125 => octal escape for 'U'
4    => '4'
4    => '4'
-
\655 => octal escape for... (something)
1    => '1'
9    => '9'

: Etkin aynıdır hangi

[^14-\655]

Ne \655 bir dizi üst olarak gelir belli değil, ama karakter sınıfı, '1 ', '4', veya ''4 daha kod noktası daha yüksek olan herhangi bir ASCII karakter dışında bir şey maçlar (ki '9 içerir 've "U"). Gerçekten olsa farketmez; önemli nokta sekizlik kaçar ihtiyaçlarınız için onları uygunsuz kılan üç basamaklı en fazla içerebilir olmasıdır. Ben yerine PHP'nin \x{nnn} onaltılık gösterimde kullanmanızı öneririz.

PHP veya Çince biriyle çalışmak için kurulmuş değilim, bu yüzden size kesin bir cevap veremem, ama bu en az olmalıdır yardım soruyu rafine. Gördüğüm kadarıyla, temelde dört aşamalı bir süreç:

  • boşlukla onları yerine, noktalama gibi istenmeyen karakterlerin kurtulmak

  • boşluk normalleştirmek: öncü ve sondaki boşlukları kurtulmak ve bir boşluk için iki veya daha fazla boşluk çalışır çökecek

  • davayı normalleştirmek: kendi küçük eşdeğerleri ile herhangi bir büyük harf değiştirin

  • Çinli bir karakter başka bir boşluk olmayan karaktere yanında yerde, bir boşluk iki karakter ayrı

İlk üç adımlar için, deftere kod ilk satırı yeterli olacaktır:

$str = mb_strtolower(trim(preg_replace('#[^\p{L}\p{Nd}\.]+#u', ' ', $str)));

Nihai adım için, ben lookarounds öneririm:

$str = preg_replace(
    '#(?<=\S)(?=\p{Chinese})|(?<=\p{Chinese})(?=\S)#u',
    ' ', $str);

Yani sonraki karakter Çin ve önceki karakter boşluk değil, ya previous karakter Çin ve next karakter boşluk olmayan herhangi bir pozisyonda bir boşluk eklemek gerekir.