pattern مناسب برای تغییر بخشی از متن...

NabiKAZ

Well-Known Member
سلام
سوالم رو به صورت مثال مطرح میکنم.
فرض میکنیم این کد رو کاربر در فرم وارد میکنه :
کد:
Hello, [bold]how are[/bold] you?
حال میخوام با php قبل از اینکه این کد به خروجی ارسال بشه اون تیکه بین [bold] و [bold/] به صورت bold نمایش داده بشه، اینجوری:
کد:
Hello, <strong>how are</strong> you?
البته ممکنه لازم باشه که یه سری توابع هم روی اون بخش از متن که محدود به تگ [bold] است ، پیاده بشه و فقط محدود به bold کردن نباشه. (منظور اینه که رشته ای که در تگ است باید به یه تابع پاس داده بشه و مقدار بازگشتی جایگزین بشه.
چه راحی پیشنهاد میکنید.
البته میدونم بهترین راه استفاده از eregi_replace است ولی pattern مناسبش رو نتونستم بنویسم.

نبی
 
آخرین ویرایش:

mosi20

Active Member
حالشو ببر
PHP:
if( preg_match("'\[bold\](.*?)\[/bold\]'i",  $GLOBALS['c_main'] , $match)){
 

NabiKAZ

Well-Known Member
سلام ؛
این تابع فقط طبق الگو مقادیر رو در آرایه دسته بندی میکنه.
مقادیری که در آرایه قرار میگره قابل بازگشت به متن اصلی نیستند. در واقع فقط استخراج صورت میگیره.
الزاما و تنها باید دو طرف عبارت [bold] و [bold/] قرار بگیره تا با الگو مطالبقت کنه در صورتی که هیچ الزامی نیست و ممکنه قبل و بعد از این الگو کارکترهای دیگری باشند...
فقط برای اولین رشته ای که مطابق الگو باشه جواب میده و مابقی رشته رو در نظر نمیگیره.
و...
در کل اون چیزی نبود که میخواستم .
با همه اینها ممنونم.

البته خودم کمی گشتم و یه همچین چیزی تونستم بنویسم:
کد:
function bold($s) {
return "<b>".$s."</b>";
}
$parsed_code = 'salam  [bold] khoobi, [/bold] in yek matn azmayeshi ast.';
$parsed_code = preg_replace("/(\[bold\])(.*)(\[\/bold\])/e", 
             "bold('\\2')", 
             $parsed_code);
echo $parsed_code;

براحتی هم قابل پاس دادن به تابع و جایگزینی مقدار برگشتی است.
البته این هم اشکالش اینه که تمامی رشته بین اولین [bold] و آخرین [bold/] رو پررنگ میکنه.
یعنی در مورد این رشته خوب کار نمیکنه:
کد:
'salam  [bold] khoobi, [/bold] in [bold] yek matn [/bold] azmayeshi ast.'

این مشکل رو هم موقتاً اینطوری حل کردم:
کد:
function bold($s) {
return "<b>".$s."</b>";
}
$parsed_code = 'salam  [bold1] khoobi, [/bold1] in [bold2] yek matn [/bold2] azmayeshi ast.';
$parsed_code = preg_replace("/(\[bold([0-9]*)\])(.*)(\[\/bold(\\2)\])/e", 
             "bold('\\3')", 
             $parsed_code);
echo $parsed_code;
در واقع به کلک زدم و برای هر تگ ، یه شماره اختصاصی اختصاص دادم که مشخص باشه کدون تگ کجا بسته شده.
اگر این مشکل آخر هم حل بشه و کدی باشه که براحتی برای متن زیر جواب بده همون چیزیه که من میخوام:
یعنی این رو :
کد:
'salam  [bold] khoobi, [/bold] in [bold] yek matn [/bold] azmayeshi ast.'
به این تبدیل کنه:
کد:
'salam  <b> khoobi, </b> in <b> yek matn </b> azmayeshi ast.'
(و البته محدودیت تعداد تگ نداشته باشه)


نبی
 

mosi20

Active Member
سلام
خوبی؟
این کارا چیه میکنی؟
مگه php موردس که تو شماره گزاری کنی؟
PHP:
<?
$data='salam  [bold] khoobi, [/bold] in [bold] yek matn [/bold] azmayeshi ast.';
@preg_match_all("'\[bold\](.*?)\[/bold\]'s", $data, $matches);
for($i = 0; $i < count($matches[1]); $i++){
	$data=str_replace('[bold]'.$matches[1][$i].'[/bold]', '<b>'.$matches[1][$i].'</b>' ,$data);
}
print $data;
?>
 

oxygenws

Active Member
بهتر نیست خیلی راحت «[bold]» رو با «< b >» جایگزین کنی؟؟ یعنی با str_replace؟؟
 

mosi20

Active Member
در این مورد چرا اینکار را هم میشه کرد اما من روش کلی این کارارو توضیح دادم.
در این مورد حق با شماست
 

oxygenws

Active Member
البته این چیزی که من گفتم زمانی می تونه مشکل دار بشه که طرف فقط یه دونه [bold] بزنه و نبندش!!! اونوقت تمام متن تا آخر صفحه بولد میشه : ))
 

NabiKAZ

Well-Known Member
سلام
خوبی؟
این کارا چیه میکنی؟
مگه php موردس که تو شماره گزاری کنی؟
PHP:
<?
$data='salam  [bold] khoobi, [/bold] in [bold] yek matn [/bold] azmayeshi ast.';
@preg_match_all("'\[bold\](.*?)\[/bold\]'s", $data, $matches);
for($i = 0; $i < count($matches[1]); $i++){
	$data=str_replace('[bold]'.$matches[1][$i].'[/bold]', '<b>'.$matches[1][$i].'</b>' ,$data);
}
print $data;
?>



البته کاری که تو کردی اسمش که شماره گزاری نیست، و اون شماره گزاری هم که من کردم فلسفش یه چیز دیگه بود و اصلا ربطی به کاری که تو کردی نداره . یادت باشه من دارم از preg_replace استفاده میکنم و تو داری از preg_match استفاده میکنی که اصلا این دو خیلی فرق دارند...

با همه اینها با اون preg_match_all که استفاده کردی تقریبا مشکل رو حل کردی ، این شد یه چیزی...
اینطوری میشه [matches[1][$i$ رو به تابع پاس بدم و مقدار بازگشتی رو هم جایگزین کنم .
در کل فکر کنم همون چیزی باشه که میخواستم . ولی باید بیشتر روش کار کنم ...

بازم ازت ممنون که کمک کردی دوست عزیز.
نبی
 

NabiKAZ

Well-Known Member
بهتر نیست خیلی راحت «[bold]» رو با «< b >» جایگزین کنی؟؟ یعنی با str_replace؟؟

نه نه نه !
همون طور که گفتم ، خود تگ [bold] یه بهونست و هدف اصلی رشته بین تگ هست که باید یه پردازش روش صورت بگیره ... در واقع مجبوریم با الگوی مشخص رشته بین این تگ فرضی رو بخونیم و پس از آنالیز و تغییر دلخواه اون رو به جای اصلیش برگردونیم.

آخه دارم یه ادیتور bbmycode مینویسم، و برای نمایش کدهای php به کاربر برای اینکه رنگی و تمیز تر نمایش داده بشن از اسکریپت GeSHi استفاده کردم. بنابراین مجبورم که اگر کد php یی بین مثلا تگ [mycode] و [mycode/] قرار گرفت اون رو به توابع GeSHi ارسال کنم و خروجی که یه کد html است رو جایگزین کنم و ضمنا دیگه کدهای [mycode] دیده نشن .
مثلا توی ادیتور این کد نوشته بشه:

کد:
سلام
جهت نمایش مقدار متغییر از کد زیر استفاده نمائید:
[mycode]
<?PHP
echo $majidonline;
?>
[/mycode]
بای

قسمتی که بین [mycode] است به تابع مربوطه ارسال بشه و تبدیل بشه و نهایتا به این کد بدل بشه:

کد:
سلام<br />
جهت نمایش مقدار متغییر از کد زیر استفاده نمائید:<br />
<pre class="php" style="color: #000066; border: 1px solid #d0d0d0; background-color: #f0f0f0;"><span style="color: #000000; font-weight: bold;">&lt;?PHP</span>
<a href="http://www.php.net/echo"><span style="color: #000066;">echo</span></a> <span style="color: #0000ff;">$majidonline</span>;
<span style="color: #000000; font-weight: bold;">?&gt;</span>
&nbsp;</pre>
بای<br />

راستی آواتار نو مبارک ;-)

تشکر
نبی
 
آخرین ویرایش:

bahy_my

Active Member
سلام
می بخشید مزاحم شدم من مبتدی.
اما به نظر من حرف امید جان بهتره.(منظورم استفاده از تابع str_replace )
کد مربوط به تاپیک رو بذارید کنار.
اگه ما کلا بخوایم که به هیچ وجه <,> رو ترجمه نکنه. ینی در حقیقت تبدیلشون کنه (&lt;....) استفاده از این کد مناسب نیست :
preg_replace
چون اگه تگی بین تگ اولیه باشه, ینی به این شکل :
<?php
<html>

?>
این کد رو اونظوری که ما می خوایم Replace نمی کنه. فقط <?php و ?> رو تبدیل می کنه.(امتحان کردم)
اما str_replace این کار رو بدون نقص انجام داد.
==============================
آقا من عذر می خوام مثه قاشق نشسته پریدم وسط حرفاتونااا !! :)دی)
 

NabiKAZ

Well-Known Member
مراحمی عزیز.

من یه سوال پرسیدم و با راهنمایی دوستان و preg_match_all به جواب رسیدم و مشکلم حل شد.

دلیل استفاده نکردن از روشی که امید گفت رو هم کامل و مفصل توضیح دادم.

ولی من متوجه منظورت نشدم. شما دقیقا بگو چیکار میخوای بکنی تا شاید راه حلی ارائه بشه.


نبی
 

bahy_my

Active Member
بله
ممنون
ببین.. فرض کن یه کد php داریم که توش یه کد html درج شده.مثلاً :
PHP:
$OUR_TEXT="
<?php

print '<br>';

?>
";
الان تو اینجا, اگه بخوایم کارکترهای html رو تبدیل کنه (&glt; , &lt;) در صورت استفاده ی preg_replace اون کد html داخلی تبدیل نمیشه.
اما با str_replace میشه.
همین.
من اونو امتحان کردم.
آیا روش بهتری هست ؟
 
آخرین ویرایش:

md5

Member
عزیزم تابعی که تو بهش نیاز داری
preg_replace_callback()
هستش در ضمن نیازی به شماره گذاری هم نبود
میتونستی با قرار دادن یه ؟ قبل از بستن پرانتز به نتیجه برسی
 

md5

Member
PHP:
function bold($matches) {
	return "<b>".$matches[1]."</b>";
	}
$parsed_code = 'salam  [bold] khoobi, [/bold] in [bold] yek matn [/bold] azmayeshi ast.';
$parsed_code = preg_replace_callback("/\[bold\](.*?)\[\/bold\]/si","bold",$parsed_code);
echo $parsed_code;
 

NabiKAZ

Well-Known Member
PHP:
function bold($matches) {
	return "<b>".$matches[1]."</b>";
	}
$parsed_code = 'salam  [bold] khoobi, [/bold] in [bold] yek matn [/bold] azmayeshi ast.';
$parsed_code = preg_replace_callback("/\[bold\](.*?)\[\/bold\]/si","bold",$parsed_code);
echo $parsed_code;

روش شما هم خوب بود ممنون .
البته من از این روش خوب جواب گرفتم:
PHP:
      preg_match_all("'\[bold\](.*?)\[/bold\]'s", $text, $matches);
      for($i = 0; $i < count($matches[1]); $i++){
          $text = str_replace('[bold]'.$matches[1][$i].'[/bold]', bold($matches[1][$i]), $text);
      }
 

my friend

Member
سلام ، تو چند تا سایت + مجید آنلاین سرچ کردم و نتیجه ای نگرفتم ، میل زدم به آقای نبی و آدرس این صفحه رو دادن.
اما مشکلم حل نشد.
این هم سوالم ، لطفا جواب بدید:
من نیاز به یک عبارت منظم دارم. که کلمه
salam
رو از کد زیر بگیره

[a]XXX[/a]
البته فقط به شرطی XXX رو بگیره که داخل تک s باشه و تگ s هم داخل تگ a
تگ s تو هر قسمت از a میتونه باشه ، مثلا قبلش ممکنه متنی نوشته شده باشه یا بعدش متنی نوشته شده باشه
لطف کنید و زودتر جواب بدید.

ممنون.
 
آخرین ویرایش:

NabiKAZ

Well-Known Member
بفرما عزیز:
PHP:
<?php
$body = "[a]1[s]salam[/s][/a]";
echo eregi_replace("\[a\].*\[s\](.*)\[\/s\].*\[\/a\]", "\\1", $body);
?>

نبی
 

my friend

Member
دستت درد نكنه نبي جان،

اون پترنش رو يه تغيير كوچولو دادم تا اگه متني بين تگهاي a و b بود رو نشون نده.
اما يه مشكل وجود داره!
اگه تگ b وجود نداشته باشه كل متن بين تگ a رو نشون ميده و اگه تگ a وجود نداشته باشه تمامي مقدار body$ رو نشون ميده:
اين كد اصلاح شده:
PHP:
$body = "[a]
[b]Hello World!!![/b]
[/a]";

$name = eregi_replace(".*\[a\].*\[b\](.*)\[\/b\].*\[\/a\].*", "\\1", $body);
اين هم نشون دهنده عمق فاجعه:
PHP:
$body = "[a]
Hello World!!!
[/a]";

$name = eregi_replace(".*\[a\].*\[b\](.*)\[\/b\].*\[\/a\].*", "\\1", $body);
 
آخرین ویرایش:

جدیدترین ارسال ها

بالا