• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Wyrażenia regularne (PHP) a znaki z różnych języków

VPS Starter Arubacloud
+1 głos
240 wizyt
pytanie zadane 2 maja 2017 w PHP przez TeslaX93 Gaduła (3,590 p.)

Dzień dobry. Nie jestem zbytnio obeznany w wyrażeniach regularnych, dopiero zaczynam ich naukę. 

Chciałem z PHPowego stringa pozbyć się wyrazów, które są krótsze niż 4 znaki. Dotychczas ten kod spełniał swoją rolę:

$copydoc = trim(preg_replace("/[^a-ząćęłńóśźż0-9']+([a-ząćęłńóśźż0-9']{1,3}[^a-ząćęłńóśźż0-9']+)*/ui"," "," $copydoc "));

Problem jednak nastąpił, gdy użytkownik wprowadził znaki z cyrylicy, i wówczas powyższy kod nie dał sobie rady. Pytanie brzmi - jak można zmodyfikować powyższe wyrażenie, aby odrzucał dowolne, krótkie wyrazy z dowolnego języka? 

1 odpowiedź

0 głosów
odpowiedź 2 maja 2017 przez Chess Szeryf (76,710 p.)
wybrane 11 stycznia 2019 przez TeslaX93
 
Najlepsza

Napisz if'a, który będzie sprawdzał, czy preg_match()==1. Jeśli jest równy 1, to będzie oznaczać, że ktoś wpisał właśnie od 1 znaku do 3 znaków to wykonaj kod z preg_replace().

Oto ci chodziło:

$zmienna='ddd45';
if(preg_match("@^.{1,4}$@",$zmienna,$matches)==1){
	echo 'To ma od 1. do 4. znaków';
}else{ 
	echo $zmienna;
}

?

Czy oto:

<?php
$keywords = preg_split("/[\s]+/", "hypertext language programming 1234 ");

for($i=0;$i<=count($keywords)-1;$i++){
	
$numerek=$i;

	if(strlen($keywords[$numerek])>=1 && strlen($keywords[$numerek])<=4){
		echo $keywords[$numerek];
	}else{ 
		echo null;
	}
}
?>

Czy o taki kod:

<?php
$subject='tak wiecejznakow jest muschroms nic';
 
echo preg_replace_callback_array(
[
    '@[a-z]+ ?@' => function ($match){
        if(strlen($match[0])>=1 && strlen($match[0])<=5) {
            null;
            #var_dump($match);
        }else{
            echo $match[0];
            #var_dump($match);
        }
    }
]
,$subject);
 
?>

Jeśli będzie np.:

$subject1='wwww ';//zniknie
$subject2='wwwww';//zniknie
$subject3='wwwww ';//nie zniknie

// Mimo iż w $subject3 Jest 5 znaków nie czyści pola, dlaczego? 
// Otóż musisz poprawić wzorzec lub kod, aby  jeśli na końcu jest spacja, to żeby ją zignorował, bo teraz liczy tak jakby było 6 znaków, a nie 5.

// Mimo iż w $subject3 Jest 5 znaków nie czyści pola, dlaczego?
// Otóż musisz poprawić wzorzec lub kod, aby  jeśli na końcu jest spacja, to żeby ją zignorował, bo teraz liczy tak jakby było 6 znaków, a nie 5.

Tak, więc musisz lekko zmodyfikować wzorzec lub kod.

Podstaw za $subject w moim kodzie powyżej $subject1, $subject2 i $subject3 i posprawdzaj sobie.

Inna wersja tego kodu:

 
<?php 
$subject=trim('rybak rybak co chcesz qwert czosnek qqqeet   ');
 
 
echo preg_replace_callback_array(
[
    '@[a-z]+@' => function ($match){
        if(strlen($match[0])>=1 && strlen($match[0])<=5) {
            null;
			
        }else{ 
            echo $match[0].' ';
			
        }
    }
]
,$subject);
 
?>

Poprawiłem lekko tamten kod i teraz gdy wystąpi takie coś, gdy jest warunek

if(strlen($match[0])>=1 && strlen($match[0])<=5)

to teraz nie ma takiego czegoś:

'rybak '

tylko

'rybak'

Sprawdź to var_dump'em.

Ta wersja kodu usuwa także ostatnią spację z wyniku. Trzeba tylko przetestować ten kod źródłowy:

<?php 
$subject=trim('rybak rybak co chcesz qwert czosnek qqqeet   ');
 

echo trim(preg_replace_callback_array(
[
    '@[a-z]+@' => function ($match){
        if(strlen($match[0])>=1 && strlen($match[0])<=5) {
            null;
             
        }else{ 
			/*if($match[0]==end($match)){
				$spacja='';
			}else{ 
				$spacja=' ';
			}*/
            $spacja=' ';
            echo $match[0].$spacja;
            
        }
    }
]
,$subject));
  
?>

Oczywiście nie wiem, czy te trim() są tam potrzebne, ale mniejsza oto. Wyżej załączony kod jest taki sam jak ten powyższy, zakomentowałem tylko jedną część.

Przetestowałem i się okazuje, że ten kod powyżej jest raczej błędny jeśli odkomentujemy tą zakomentowaną część.

Nie raczej tylko chyba na pewno.

Jeśli np. masz taki kod:

$subject=trim('rybak rybka widac widok niechciec drzewo tree 1234 lolek cotam trzeba have doing having frouping mouse');
 

To, aby usunąć z niego ostatnią spację trzeba:

if($match[0]=='frouping'){
                $spacja='';
            }else{ 
                $spacja=' ';
            }
			
             echo $match[0].$spacja;

Tylko w tym wypadku trzeba znać nazwę ostatniego elementu, ale jak to zrobić automatycznie.

To działa, ale trzeba ręcznie wpisać nazwę ostatniego elementu, który ma więcej znaków niż 5:

<?php 
$subject=trim('rybak rybak co chcesz qwert czosnek qqqeet trelemorele');
  
 
echo trim(preg_replace_callback_array(
[
    '@[a-z]+@' => function ($match){
        if(strlen($match[0])>=1 && strlen($match[0])<=5) {
            null;
              
        }else{ 
              if($match[0]=='trelemorele'){
                $spacja='';
            }else{ 
                $spacja=' ';
            } 
             
            echo $match[0].$spacja;
             
        }
    }
]
,$subject));
   
?>

Lecz jeśli wystąpią 2 takie same wyrazy o tej samej nazwie, to usunie też spację ze środka! z tego miejsca, gdzie wystąpił dany wyraz.

 <body style="background:green;white-space:none">
<?php
$subject=trim('tak wiecejznakow jest muschroms nic');
  
echo (trim(preg_replace_callback_array(
[
    '@[a-z]+ @' => function ($match){
       
           if(strlen($match[0])>=1 && strlen($match[0])<=5) {
            null;
            #var_dump($match);
        }else{
            echo $match[0];
            #var_dump($match);
        }
    }
]
,trim($subject),-1)));
  
?>
<br /><br />



 '@[a-z]+ |[a-z]+@'
 
<?php 
$subject=trim('string string string');

  
echo trim(preg_replace_callback_array(
[
    '@[a-z]+@' => function ($match){
        if(strlen($match[0])>=1 && strlen($match[0])<=5) {
            null;
               
        }else{ 
              if($match[0]=='trelemorele'){
                $spacja='';
            }else{ 
                $spacja=' ';
            } 
          
           echo $match[0].$spacja;
			
			 

			
              
        }
    }
]
,$subject,0));
    
?>

Rozwiązanie ze zmiennymi globalnymi, ale jak to zrobić bez zmiennej globalnej.

 <body style="background:green;white-space:none"><pre>
<?php 
 
$subject= ('co chciales bo nie wiem dzikus');

$pieces = explode(' ', $subject);
$last_word = array_pop($pieces);

 

if(strlen($GLOBALS['last_word'])>=1 && strlen($GLOBALS['last_word'])<=5){
	global $myvariable;
	$myvariable=$last_word;
	//echo 'to slowo ma' . strlen($last_word) . ' znaków' ; 
}else{ 
	//echo 'to slowo ma wiecej niz 5 znakow<br />';
	   $GLOBALS['last_word'];
	 ///echo $_GLOBALS['last_word'];
	 
	 
	//echo 'to slowo ma' . strlen($last_word) . ' znaków' ; 
}

/*var_dump*/( (preg_replace_callback_array(
[
    '@[a-z]+@' => function ($match){
        
         // var_dump(($match ));
			 //print_r( $match[0]."");
			  // print_r($match);
			  
			   if(strlen($match[0])>=1 && strlen($match[0])<=5) {
              //print_r($match);
               //print_r($match[0].' ');
			  //var_dump($match[0]);
			  
			 // print_r(end($match  ));
			}else{ 
				  
				  //print_r(trim($match[0]));
				 // print_r($match);
				//var_dump($match[0]);
				//$_GLOBALS['myvariable2']='dzikus';
				if($match[0]==$GLOBALS['last_word']){
                $spacja='';
				}else{ 
					$spacja=' ';
				}
				 
				 echo($match[0].$spacja);
				
			}
			 
			
              
        }
    
]
,($subject),-1)));
?>
<?php
$subject = 'ide sobe na lace banany cias kremem';

$teksior=(trim(rtrim(preg_replace_callback_array(
    [
        '~[a-z]+~' => function ($match) {
				return  $match[0];
        },
        '@(([ ])+$)+@' => function ($match) {
			return null;
        },
		'@^(([ ])+)+@' => function ($match) {
			return null;
		},
		'@ +@' => function ($match) {
			return ' ';
		},
		'@\b[a-z]{1,4}\b@' => function ($match) {
			return '';
		}
    ],
    $subject
))));

var_dump($teksior);
echo preg_replace('@ +@',' ',$teksior);
?>

Ostatni kod, który napisałem jest najprawdopodobniej rozwiązaniem do tego zadania, które padło w temacie:

Modified:

<body style="background:green"><pre>

<?php
$subject = 'qqqq4  !@#$% $$$$ ΨΨΨΨΨ  <>><<>>>> aaaa isc         goscie teraz lubic to kiedys niewiemesdfd';
 
$teksior=(trim((preg_replace_callback_array(
    [
        '~((.)+)~' => function ($match) {
				return  $match[0];
        },
        '@(([ ])+$)+@' => function ($match) {
			return null;
        },
		'@^(([ ])+)+@' => function ($match) {
			return null;
		},
		'@ +@' => function ($match) {
			return ' ';
		},
		'@\b(.){1,4}\b@' => function ($match) {
			return ' ';
		} ,
		'@\b([^a-zA-Z0-9]+)\b@' => function ($match) {
			return ' ';
		} 
    ],
    $subject
))));

 #var_dump($teksior);
 echo preg_replace('@ +@',' ',$teksior);
?>

</body>
<body style="background:green"> 
 
<?php
$subject = '[\]777777\\\\\\\\\qqqq4][65654\[]][\][]\\\\///@##@@#  !@#$% $$$$ ΨΨΨΨΨ  <>><<>>>> ΨΨΨaaΨΨΨaaΨΨΨ isc [\]   ΨΨΨ     goscie teraz lubic to kiedys niewiemesdfd';
  
$teksior=(trim((preg_replace_callback_array(
    [
        '~((.)+)~' => function ($match) {
                return  $match[0];
        },
        '@(([ ])+$)+@' => function ($match) {
            return null;
        },
        '@^(([ ])+)+@' => function ($match) {
            return null;
        },
        '@ +@' => function ($match) {
            return ' ';
        },
        '@\b(.){1,4}\b@' => function ($match) {
            return ' ';
        } ,
        '@\b([^a-zA-Z0-9\-]+)|^([^a-zA-Z0-9\-]+)\b@' => function ($match) {
            return ' ';
        } 
    ],
    $subject
))));
 
 var_dump($teksior);
 //echo preg_replace('@ +@',' ',$teksior);
?>
 
</body>
<?php
$m= $_POST['text'];
var_dump($m);
//$x=preg_replace('@ +@',' ',$m);
 echo '<br /><br />';
 
var_dump(( (preg_replace('@ +|\b([\s]){1,3}\b@','%',/*var_dump*/ $m))));

# '@[^\s\p{L}]|\b([\s\p{L}]){1,3}\b@u'
?>
echo preg_replace('/(?<!\S)\S{1,4}(?!\S)/u','%', $s);

UWAGA!!!

Żaden z powyższych kodów nie jest najlepszy, ponieważ trzeba, któryś z nich lekko zmodyfikować lub nieco bardziej, ponieważ dokleja bądź nie spację!!!

<?php
$m= '       d         f    fede  koleś.,.,.. [] ^*&^&xdxe$xdxe^#&$^#& ^ Polska terenowy    SZkó$łda    ';
// var_dump(  (preg_replace('@[^dsfg](\S)+[^dsfg]@','%',/*var_dump*/ $m)));
 $x=preg_replace('@ +@',' ',$m);
 
 var_dump( (trim (preg_replace('@[^\s\p{L}]|\b([\s\p{L}]){1,3}\b@u',' ',/*var_dump*/ $m))));

// /^[\s\p{L}]+$/u
#  var_dump(  (preg_replace('@[^dsfg](\S)+[^dsfg]@','%',/*var_dump*/ $m)));
# var_dump( trim (preg_replace('@[^\s\p{L}]|\b([\s\p{L}]){1,3}\b@u','%',/*var_dump*/ $m)));

?>
<?php
 echo  ($_POST['text']);
echo '<br /><br />';
 echo $p= preg_replace('/(?<!\S)\S{1,4}(?!\S)/u','%', $_POST['text']); 
echo '<br /><br />';
 $d= trim(preg_replace('@[^a-zA-ZąęółźżĄĘÓŁŹŻśŚ]@','!',$p));
  echo '<br /><br />';
  echo $d;
 echo '<br /><br />';
var_dump(trim(preg_replace('@!+@',' ',$d)));
 
 ?>

Uwaga!!! Każdy z powyższych kodów trzeba dokładnie przeanalizować i przetestować w celu wykrycia błędów!

Zastrzegam sobie nie brania odpowiedzialności za błędne działanie skryptu do tego pytania:

Chciałem z PHPowego stringa pozbyć się wyrazów, które są krótsze niż 4 znaki.

 

Ostatnia Uwaga:

- Jeśli cokolwiek działa błędnie, są doklejane spacje na końcu, na początku itd., itp. lub coś działa tak jak nie należy lub występuje cokolwiek błędnego co do pytania zadanego przez użytkownika TeslaX93 to przepraszam

W skrócie:

- Zastrzegam sobie nie brania odpowiedzialności za merytoryczność wypowiedzi w tym temacie oraz jakoś napisanego kodu. Jeśli użyjesz jednego z powyższego kodu i wyrządzi to Tobie jakieś szkody, to nie biorę za to odpowiedzialności.

Jeżeli ktoś użyje mojego skryptu, np. aby sprawdzał czy dane słowo ma od 1 do 4 znaków i  aby je zamieniał na np. spację i jeśli coś się "wysypie", że np. użytkownik wpisze w pole $_POST['text'] jakiś tekst i jeśli zostanie błędnie, źle przeredagowany z założeń skryptu to przepraszam.

Jeśli użytkownik wpisze w pole $_POST['text'], np. takie dane:

"Example, Exam ple ple"

I jeżeli wyrzuci coś takiego:

"?, Exam ple ?"

Lub jakieś inne niezgodne z założeniami skryptu, to znaczy, że źle działa, ponieważ powinien wypluć:

"Example, ? ? ?"

lub jakiś inny string.

Podobne pytania

0 głosów
2 odpowiedzi 308 wizyt
pytanie zadane 24 kwietnia 2017 w Java przez Swierzak Użytkownik (690 p.)
0 głosów
1 odpowiedź 194 wizyt
0 głosów
1 odpowiedź 168 wizyt
pytanie zadane 7 stycznia 2019 w Python przez Frezen Obywatel (1,330 p.)

92,454 zapytań

141,262 odpowiedzi

319,098 komentarzy

61,854 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Akademia Sekuraka 2024 zapewnia dostęp do minimum 15 szkoleń online z bezpieczeństwa IT oraz dostęp także do materiałów z edycji Sekurak Academy z roku 2023!

Przy zakupie możecie skorzystać z kodu: pasja-akademia - użyjcie go w koszyku, a uzyskacie rabat -30% na bilety w wersji "Standard"! Więcej informacji na temat akademii 2024 znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...