v2.5.2
Giriş yap

Cümle İçerisinde Arama

acemi
579 defa görüntülendi ve 1 kişi tarafından değerlendirildi
// filtre.json
{
    "kelimeler":[
        "******",
        "s....",
        "g....",
        "a...."
        ]
}
Class Filtre {
    public $dosya = "filtre.json"; 
    public function Filtre($Filtre){
        $File = file_get_contents($this->dosya);
        $File = json_decode($File);
        $File = $File->kelimeler;
        $response = [];
        foreach ($File as $key => $value) {
            $response[] = [$value];
        }
        $Result = json_encode($response);
        $String = strstr($Result, $Filtre); 
        if($String === false):
            return false;
        else:
            return true;
        endif;
    }
}

arkadaşlar böyle birşey yaptım fakat istediğim gibi çalışmıyor.

cümle içerisinde

    $kelime = "Uzaylı seni yakalarsam ****** içinden geçerim";
    $Filtre = new Filtre();
    print_r($Filtre->Filtre($kelime));
    
    sonuç false dönüyor true dönmesi lazım fakat
    $kelime = "******";
    $Filtre = new Filtre();
    print_r($Filtre->Filtre($kelime));
    

cümle içerisinde tam bir arama yapmak istiyorum yardımcı olurmusunuz bununla ilgili.

Cevap yaz
Cevaplar (18)
abdullahx
574 gün önce

Üzerinde epeyi uğraştım, son hâlini alana kadar türlü revizyondan geçti. Ama yine de yüzde yüz engellemeyebilir. Aklıma geldiği kadarını eklemeye çalıştım.


class Filter
{
    protected $dosya;
    const STARS = '*****';

    public function __construct()
    {
        $this->dosya = json_decode(file_get_contents(__DIR__ . DIRECTORY_SEPARATOR . 'filtre.json'), true)['kelimeler'];
    }

    private function explode($words)
    {
        $list = ['.',',',':',';','!','?','=','-','_','/','\\','%','&','(',')','{','}','[',']','\'','"','*','+','^','#','$','@','₺','€'];
        $words = trim(str_replace($list, ' ', $words));
        preg_match_all('/(\b\S+\b)/u', $words, $matches);

        $recursive = function ($arg, $k, $v) use (&$recursive) {
            static $arr;
            $newArr = array_chunk($arg, $k);

            $newStr = mb_strtolower(implode(' ', $newArr[0]));
            $arr[$newStr] = in_array($newStr, $v);
            array_shift($arg);

            if (count($arg) && count($arg) >= $k) {
                $recursive($arg, $k, $v, $arr);
            }
            return $arr;
        };

        $results = [];
        if (count($this->dosya)) {
            foreach ($this->dosya as $k => $v) {
                $results = $recursive($matches[0], $k, $v);
            }
        }
        return $results;
    }

    /**
     * @param $username
     * @return void
     * - Bu metod usernameFilter metodunun test hâlidir, yasaklı kelime ile eşleştiğinde echo ile yazdırabilmek için kullan, asıl çalışan metod üstteki, testten sonra bu metodu silebilirsin
     */
    public function usernameFilterForTest($username)
    {
        $results = $this->explode($username);
        if (count($results)) {
            foreach ($results as $k => $v) {
                if ($v) {
                    echo "Yasaklı kelime bulundu. Eşleşen kelime <b>$k</b><br>";
                    // Kullanıcı adı yasaklı kelimeler listesinde bir şekilde var
                    // Kullanıcı adı bir kelime veya bir kelimeden fazla ise bile eşleşme sağlanıyor. 3 kelimeli bir ad olsa ve son iki kelimesi, yasaklı kelimeler listesinin 2 kelimelik listesinde varsa bile eşleşme sağlanır
                }
            }
        }
    }

    /**
     * @param $comment
     * @param bool $one2oneFilter - Yorum içerisinde bulunan yasaklı kelimelerin kendi harf sayılarına göre filtrelenme seçeneği. Örneğin yasaklıKelime kelimesi bulunduğunda bu değer true ise kendi harf sayısı kadar * koyulur *************; false ise alttaki STARS sabitindek, kadar yıldız koyulur
     * @param bool $forceFilter - Bu da aslında sizin 'komple bir metnin içeriğinde kelime avına çıkma' isteğiniz için bir seçenek. true verilirse yasaklı bir kelime başka bir kelimenin içinde bulunsa bile filtrelenir. false ise sadece tam olarak bir kelime şeklinde yasaklı listesinde varsa filtrelenir
     * @return array|string|string[]|null
     */
    public function commentFilter($comment, bool $one2oneFilter = true, bool $forceFilter = false)
    {
        $results = $this->explode($comment);
        $filter = array_filter($results, function ($item) {
            return $item;
        });
        $h = array_map(function ($item) use ($forceFilter) {
            if ($forceFilter)
                return "/$item/i";
            else
                return "/\b$item\b/i";
        }, array_keys($filter));

        if ($one2oneFilter) { // Eğer * işaretlerini filtrelenen kelimenin tam harfleri ile uyumlu şekilde koymak istiyorsak
            $replacemenet = [];
            for ($i = 0; $i < count($h); $i++) {
                $str = '';
                if ($forceFilter)
                    $a = substr($h[$i],1, -2);
                else
                    $a = substr($h[$i],3, -4);

                $p = explode(' ', $a);
                foreach ($p as $item) {
                    $str .= str_repeat('*', mb_strlen($item)) . ' ';
                }
                $replacemenet[] = $str;
            }
            $response = preg_replace($h, $replacemenet, $comment);
        }
        else
            $response = preg_replace($h, self::STARS, $comment);

        return $response;
    }

    /**
     * @param $username
     * @return bool
     * - Kullanıcı adında yasaklı kelimeler varsa false yoksa true döndürür
     */
    public function usernameFilter($username): bool
    {
        $username = trim($username);
        preg_match_all('/\pL+/u', $username, $matches);

        $results = $this->explode($matches[0]);
        if (count($results)) {
            foreach ($results as $v) {
                if ($v)
                    return false;
            }
        }
        return true;
    }
}

// Bir defa oluşturduktan sonra aşağıdaki kısmı silebilirsin
###################################
// Örnek bir yasaklı kelimeler json dosyası oluşumu. Yasaklı kelimeleri içerdikleri kelime sayılarına göre gruplandırdım. Yazdığım sınıfta buna göre bütün yasaklı kelimeleri verilen yorum veya kullanıcı adındaki kelimeleri bu listede bulunan harf sayılarına göre teker teker bölüp arıyor.
$kelimeler = [
    'kelimeler' => [
        1 => [
            'kaybol',
            'yasaklıKelime',
            'sarkozy',
            'sak1z',
            'yani',
        ],
        2 => [
            'tuvalet terliği',
            'naylon poşet',
            'yasaklı kelime'
        ],
        3 => [
            'yasaklı bir kelime',
            'üç kelime yasaklı',
            'elli birinci bölge'
        ],
        4 => [
            'zincirleme k1üfür içeren kelimeler'
        ]
    ]
];

file_put_contents('filtre.json', json_encode($kelimeler, JSON_UNESCAPED_UNICODE));
###################################

// Biraz gereksiz kod tekrarı olmuş olabilir, olabildiğince kkısa yollarla halletmeye çalıştıkça türlü sıkıntılar çıktı. Çook uzun yorumlarda belki ufak bir gecikme sorunu yaşanabilir emin değilim. Çünkü yorumu çok fazla parçaya ayırıp kontrol etmeye çalışacak. Umarım işinize yarar.

$username = 'yasaklı kelime içeren kullanıcı adı';
$filter = new Filter();
//$filter->usernameFilterForTest($username);

/******* if ($filter->usernameFilter($username)) {
// Sonuç başarılı, yasaklı kelime çıkmamış, bu kullanıcı adıyla kayıt olabilir
echo 'başarılı';
}
else {
// Sonuç başarısız, kullanıcı adının içinde bir şekilde yasaklı kleime tespit edildi, bu kullanıcı adıyla kayıt olamaz
echo 'Başarısız';
}*******/ // Orijinal kullanıcı adı kontrolü


$comment = 'Bu yorumun içerisinde yasaklı kelimeler bulunabilir. İçinde sayı olan yasaklı kelimeler de olabilir, mesela sak1z gibi. Örneğin sarkozy kelimesi yasaklı bir kelimedir ve filtrelenecektir. Aynı şekilde naylon poşet de yasaklı kelime listesinde mevcuttur.Zincirleme k1üfür içeren kelimeler de filtrelenir :) Yani kelimesi tek başına filtrelenir ama malayani veya süryanice gibi içerisinde bulunuyorsa filtrelenmeyebilir.';
$filteredeComment = $filter->commentFilter($comment);
echo "<b>Sadece tam eşleşmeler filtrelenmiş hâli</b>: $filteredeComment";
echo '<br><br>';
$filteredeComment = $filter->commentFilter($comment, forceFilter: true); // PHP 8 sözdimizi. Eğer PHP 8 değilse senin sürüm alttki yorum satırındakini kullan
//$filteredeComment = $filter->commentFilter($comment, true, true);
echo "<b>Bütün eşleşmelerin filtrelenmiş hâli</b>: $filteredeComment";
echo '<br><br>';
echo "<b>Orijinal metin</b>: $comment";
mahony
556 gün önce

@abdullahx hocam .json içeriği şu şekilde. Belki yardımcı olur.

Edit: Hocam tamam ilk sorudaki tag e göre yapmışsınız :) Harika çalışıyor. Çok teşekkür ederim. İyi ki sizin gibi bilgiyi paylaşan insanlar var. Allah razı olsun..

mahony
556 gün önce

@abdullahx hocam teşekkür ederim ancak başarılı sorgulama yapmıyor gibi görünüyor. .json dosyamda olanlarda da error hatası veriyor. Neyi gözden kaçırmış olabiliriz?

abdullahx
557 gün önce
<!doctype html>
<html lang="tr">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css">
    <title>Document</title>
    <style>
        #feedBack {
            display: none;
        }
        .success {
            color: #495057;
            background-color: #fff;
            border-color: #198754 !important;
            outline: 0;
            box-shadow: 0 0 0 0.2rem rgb(74, 185, 134) !important;
        }
        .error {
            color: #495057;
            background-color: #fff;
            border-color: #dc3545 !important;
            outline: 0;
            box-shadow: 0 0 0 0.2rem rgb(229, 88, 102) !important;
        }
    </style>
</head>
<body>

<div class="container">
    <div class="row mt-5">
        <div class="col">
            <div class="input-group">
                <input type="text" class="form-control" placeholder="Arama metnini giriniz" id="searchInput">
                <div class="input-group-append">
                    <button class="btn btn-outline-primary" type="button" id="searchButton">Ara</button>
                </div>
            </div>
            <small id="feedBack"></small>
        </div>
        
    </div>
</div>


<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.1/jquery.min.js"></script>

<script>
    const input = $("#searchInput")
    const button = $("#searchButton")
    const feedBack = $("#feedBack")
    const sets = {
        errorMessage: 'Kayıt yok',
        successMessage: 'Kayıt var',
        liveSearch: true // Canlı aramayı kapatmak için false yapın, 1000 lerce kayıt içinde canlı arama yapmak performans sorunları oluşturabilir
    };

    (function (opt) {
        const options = { // Varsayılan değerler
            liveSearch: true,
            errorMessage: 'Üzgünüz kaydınız bulunamadı',
            successMessage: 'Kaydınız başarılı',
            ...opt,
            clear: () => {
                feedBack.hide()
                input.removeClass('success error')
            },
            search: inp => {
                $.getJSON('filtre.json').then(response => {
                    let values = response.map(e => e.sw)
                    if (inp.value.length) {
                        if (values.includes(inp.value)) {
                            feedBack.html(options.successMessage).removeClass('text-danger').addClass('text-success').show()
                            input.removeClass('error').addClass('success')
                        }
                        else {
                            feedBack.html(options.errorMessage).removeClass('text-success').addClass('text-danger').show()
                            input.removeClass('success').addClass('error')
                        }
                    }
                    else
                        options.clear()
                })
            }
        }
        if (options.liveSearch) {
            input.on({
                input: function() {
                    options.search(this)
                },
                blur: options.clear
            })
        }
        button.on("click", () => {
            options.search(input[0])
        })
    })(sets)
</script>
</body>
</html>

filtre.json aynı dizinde bulunsun.
Bazı geri bildirim özellikleri istenildiği gibi çalışmayabilir. Görsel açıdan

mahony
557 gün önce

est @abdullahx hocam. Bekliyorum. Teşekkürler..

abdullahx
559 gün önce

Geçen gün sizin buldum mesajını görünce sonrasına bakmamıştım açıkçası, ardından yazdığınız mesajı görmemişim kusura bakmayın. İnşallah yarın bakacağım fırsat olursa

mahony
559 gün önce

@abdullahx hocam burlarda mıyız? Göz atma şansınız oldu mu?

mahony
560 gün önce

@abdullahx hocam şöyle basit bir mantık kurdum :) Biraz oldu ama görünüp kayboluyor:) Bunu sabtlemenin bir yolu var mı hocam? Hep gözüksün istiyorum...
Bir diğer sıkıntı da arada tüm liste görünüyor. Bunun engellemenin bir yolu var mı? Yalnızca ilgili arama görünse...
//--------------------------------------------------------

  // Else, if they hit escape; empty the result list and hide it
  //--------------------------------------------------------
  } else {

    resultList.html('<span style="color: red;">NOT WHITELISTED!</span>');
    resultList.animate({opacity: 'show'}, {duration: 10000, queue: true});
  }
mahony
560 gün önce

@abdullahx hocam araştırırken şu scripti buldum. 9 yıl önce yayınlanmış olsa da tam isteğimi karşıladı.

https://github.com/Mr-Martin/Search-through-json-file

Bunun üzerinden gidecek olursak tek bir sıkıntım kaldı. Search bara aranan text yazıldığında gayet başarılı listeliyor. Ancak aranan bulunamadığında örneğin "Üzgünüz! Üçerik bulunamadı!" gibi bir hata mesajı yazdırabilir miyiz? Belki de çok basit bir kod ama...

İlgili kod kısmı sanırım şöyle.

(function($) {
  var doc = $(document);


  //--------------------------------------------------------
  // Search products
  //
  // This function will make an AJAX request to a php file that
  // search through a json files that contains a bunch of products
  //--------------------------------------------------------
  function ajaxSearchProducts() {
    doc.on('keyup', '.search', function(e) {
      var keyCode = (window.event) ? e.which : e.keyCode;
      var resultList = $('.search-results');

      //--------------------------------------------------------
      // Check if the user press a key with number or letters or
      // backspace
      //--------------------------------------------------------
      if(keyCode <= 90 && keyCode >= 48 || keyCode == 8) {
        var value = 's=' + $(this).val();

        $.ajax({
          url: 'loadProducts.php',
          data: value,
          type: 'POST',
          dataType: 'json',
          success: function(data) {
            var results = [];
            var oddEven;

            $.each(data, function(key, info) {
              if(key % 2 == 0) {
                oddEven = 'even';
              } else {
                oddEven = 'odd';
              }

              results.push('<li class="'+oddEven+'" data-id="'+info.produkt_id+'">'+info.produkt_namn+' <span style="color: green;">WHITELISTED</span></li>');
            });
            resultList.html(results);
            resultList.animate({opacity: 'show'}, {duration: 200, queue: false});
          }
        });

      //--------------------------------------------------------
      // Else, if they hit escape; empty the result list and hide it
      //--------------------------------------------------------
      } else if(keyCode == 27) {
        $(this).val('');
        resultList.animate({opacity: 'hide'}, {duration: 200}).queue(function() {
          $(this).html('');
          $(this).dequeue();
        });
      }
    });

  }


  //--------------------------------------------------------
  // Run on document ready
  //--------------------------------------------------------
  $(function() {
    ajaxSearchProducts();
  });


}(jQuery));
mahony
560 gün önce

@abdullahx hocam ilgili bir script buldum. Üzerinde çalışıp bilgi vereceğim.

abdullahx
561 gün önce

@mahony İstediğiniz şeyin temel kısmı kolay. Önemli olan teferruatlar. Bootstrap kullanıyorsanız jquery de kullandığınızı varsayıyorum. Sorgu ajax ile mi yapılacak?

mahony
561 gün önce

@abdullahx hocam benzer bir soru olduğu için -konu sahibi hocamın izniyle- buradan yazsam sanırım sorun olmaz.

Benzer bir mantıkla içinde binlerce satır veri olan bir json dosyam var. Örnek veri şu şekilde:

[{"sw":"TR2C9F8B8Ac4874C17Ff7AeA511"},{"sw":"TRc81ea4341d2c1Ffede2e5Bdaa3"},{"sw":"TR1DD1B8DFc600677eeC77016a517"},{"sw":"0x19047545FfEaad110E1B9DE3AfC623B216848355"},{"sw":"TRA0520A809A50e68bB0f43aaE2"},{"sw":"TRF843D3d612EDdc100E61560e812bA"},{"sw":"TR750CDCa9F604aed573980D196C91"}]

Basit bir bootstrap arama formum var. Kullanıcı bu verilerden birini sorguladığında örneğin arama formuna TR2C9F8B8Ac4874C17Ff7AeA511 yazıp ara butonuna bastığında bu veri json dosyasında varsa "Kaydınız başarılı vs" değilse "Üzgünüz kaydınız bulunamadı" gibi bir ifade göstermek istiyorum. Hocama verdiğiniz cevaplarla biraz uğraştım ama alanım olmadığı için maalesef başarılı olamadım. Yardımcı olur musunuz?

h4ckdr0
569 gün önce
<?php

// bir json dosyasındaki anahtarın değerine göre arama işlemi yapan sınıf
class Filter
{
    // json dosyası
    private $jsonFile = 'filter_arr.json';

    // json dosyasındaki anahtarın değerine göre arama işlemi
    public function searchAndReturnJson($search)
    {
        // json dosyasını oku
        $json = file_get_contents($this->jsonFile);
        // json dosyasını diziye çevir
        $array = json_decode($json, true);
        // dizi içinde arama yap
        $result = $this->search($array, $search);
        // sonuç varsa json olarak döndür
        if ($result) {
            return json_encode($result);
        }
        // sonuç yoksa false döndür
        return false;
    }

    // dizi içinde arama işlemi
    private function search($array, $search)
    {
        // dizi içinde dolaş
        foreach ($array as $key => $value) {
            // anahtarın değeri aranan değerse
            if ($value == $search) {
                // anahtarın değerini döndür
                return $value;
            }
            // anahtarın değeri dizi ise
            if (is_array($value)) {
                // dizi içinde arama yap
                $result = $this->search($value, $search);
                // sonuç varsa
                if ($result) {
                    // sonucu döndür
                    // return $result;
                    return true;
                }
            }
        }
        // sonuç yoksa false döndür
        return false;
    }
}

// kullanım örneği:
require_once 'Filter.php';                          // Filter sınıfını kullanacağın sayfaya dahil et

$filter = new Filter();                             // sınıfı oluştur
$response = $filter->searchAndReturnJson('******'); // arama işlemi
if ($response) {                                    // sonuç varsa
    echo $response;                                 // sonucu ekrana yazdır
} else {                                            // sonuç yoksa
    echo 'Sonuç bulunamadı';                        // mesaj yazdır
}

acemi
574 gün önce

@abdullahx teşekkür ederim gerçekten biraz da üstüne ben bişiler eklim emeğine sağlık ilgilendin allah razı olsun kardeşim.

acemi
575 gün önce

bembeyaz sayfa çıktı :) tertemiz

aslında yapmak istediğim su
filtre.json daki verileri ile gelen kullanıcı adlarını eşleştiricem yasaklı ile eşleşiyorsa hata verditecem
bir diğer taraftan da

yorumlar içerik girdilerinde cümle içerisinde filtre.json içeriğinde kelimeler ile eşleşiyor ise
o eşleşen keliemeleri ***** gibi yazmasını istiyorum gibi deyim umarım anlatabilmişimdir.
@abdullahx

sanırım senin yaptığında json içeriğinden bir şey var 1 dönüyor
yoksa 0 true false yani.

peki komple bir metnin içeriğinde kelime avına çıksa
ama söyle birşey var yasaklı kelime de "am" var fakat "ama" yazınca "ama'nın " etkilenmemesi de lazım :)

abdullahx
575 gün önce
Class Filtre
{
    public $dosya;
    public function __construct()
    {
        $this->dosya = json_decode(file_get_contents(__DIR__ . DIRECTORY_SEPARATOR . 'filtre.json'), true);
    }

    public function filter($sentence): bool
    {
        $filtreWords = explode(' ', $sentence);
        $filtered = array_filter($filtreWords, function ($item) {
            return in_array($item, $this->dosya['kelimeler']);
        });
        return (bool) count($filtered);
    }
}

$kelime = "Uzaylı seni yakalarsam ****** içinden geçerim";
$Filtre = new Filtre();
print_r($Filtre->filter($kelime));

Mesela böyle basit bir şey yaptım, eğer verilen cümlede TAM EŞLEŞEN bir kelime varsa true yoksa false döndürür

abdullahx
575 gün önce

Buralardayım hocam, baktım gönderinize birazcık uğraştım da ama tam olarak ne yapmak istediğinize kanaat getiremedim :) Class a verilen cümle içerisinde filter.json dosyasında belirtilen kelimelerden TAM OLARAK uyuşanı varsa true yoksa false mı döndüreecek. Ya da daha spesifik bir şekilde; verilen cümlede kaç tane olduğunun önemi olmadan *** lı kelime olsa da mı döndürecek vs biraz detaya ihtiyacım var. Biraz kıt anlıyorum ben :)

acemi
575 gün önce

@abdullahx kardeşim buralardamısın :)