เรื่อง Regular Expression ครับ ช่วยทีคร๊าบ

เริ่มโดย UnzO, 22 พฤศจิกายน 2007, 17:19:23

หัวข้อก่อนหน้า - หัวข้อถัดไป

0 สมาชิก และ 1 ผู้มาเยือน กำลังดูหัวข้อนี้

UnzO

อยากจะให้เช็คว่าในข้อความมันมีภาษาไทยอยู่รึป่าวหน่ะครับ ขอแค่ ตัวอักษรในภาษาไทยแค่ตัวเดียว ก็พอแล้วครับ ผมเขียนแบบนี้ แต่มันเช็คไม่ได้ ก็งง เหมือนกันคับ
ereg("[ก-๙]","$title")

* EThaiZone ขอแก้หัวกระทู้หน่อยนะครับ พิมพ์ผิด

EThaiZone

ใช้ [\xA1-\xF9] แทนครับ
หมายถึง ascii ตัวที่ 161 ถึง 249 (แต่นี้เป็นเลขฐาน 16 นะ)
ดูอ้างอิงจาก Editplus ได้ครับ

ยกตัวอย่างอันนี้ละกัน  จากกระทู้คุณ joe อิๆ

$var = '<img src="อยากได้ข้อมูลที่อยู่ตรงนี้">
<a href="อยากได้ข้อมูลddที่อยู่ตรงนี้"</a>';

preg_match_all('#[\xA1-\xF9]#', $var, $match);

print_r($match);

UnzO

ขอบคุณมากคับ ทำได้แล้วคับ แต่มันก็มีปัญหาอีกเช่นกันคือ ในเนื้อหาที่ผมจะเช็คเนี้ย มันมีทั้ง ภาษา ญี่ปุ่น เกาหลี จีน และ ภาษาอื่นๆ ทั่วโลกครับ ทีนี้ปัญหามันก็คือ มันมองเห็นตัวหนังสืออื่นๆ ที่ไม่ใช่ ภาษาอังกฤษ เป็น จริงหมด ดูจาก Code นะครับ

if(ereg("[\xA1-\xF9]","$title")){
$status = "1";
}else{
$status = "0";
}


คือถ้ามีภาษาอื่น ปนมา มันจะให้ค่า $status เป็น 1 หมดเลยครับ :P

EThaiZone

ถูกต้องครับ เป็นแบบนั้น เพราะมันเป็นการตรวจ Ascii ครับ

ตอนนี้ผมเองก็คิดได้ กำลังวิจัย (เรียกซะหรู)
เกี่ยวกับการเช็คค่าในสภาพกรณีถ้ามาใช้ UTF-8 อยู่ครับ
เพราะมันได้รับทุกภาษา แถมไม่มีการปนของอักษรด้วย (แต่ในเชิงลึก ปนกันนั่วเนีย 555+)

กำลังคิดว่า อาจต้องเล่น มัลติไบต์

เล่นยากจริงๆ พับผ่าสิ  ;D

EThaiZone

โย่ว วิจัยเสร็จ เอ้ย ค้นคว้า..  อะไรก็แล้วแต่ (ใกล้บ้า)

preg_match_all('#[ก-๙]#u', $var, $match);


คือใช้ฟังค์ชั่นตระกูลที่รับ PCRE (ฟังค์ชั่นชื่อขึ้นต้นด้วย preg)

วิธีคือ ทำใน editplus พิมพ์ภาษาไทยกะตัวเลขปกติ
เซฟเป็น utf-8(สำคัญ)

แล้วเวลาเขียน regex ต้องมี u ต่อท้ายตัว delimiter เพื่อให้รองรับ unicode เหมือนกับตัวอย่างต้องท้าย # (สำคัญ)

เท่านี้ก็เสร็จโจร  :)

(วิธีหักดิบแบบบ้านๆ เหอๆ)

UnzO

#5
เย้ ทำได้แล้วครับ ^^  ได้รับการช่วยเหลือจาก คุณ โจ้ EthaiZone ของเรานี้เอง  ;D
เผื่อเพื่อนๆ อยากรู้นะคับ ผมจะเปิดโปงโค๊ด (พูดซ๊ะ 555)


if(preg_match("#[ก-๙]#u","$title")){
$status ="0";
}else{
$status ="1";
}


จากโค๊ดด้านบน จะได้ว่า ถ้า String ที่ตรวจสอบ มี ก-๙ คือ รวมทั้ง สระ ด้วย จะให้ค่าเป็นจริงทำวงเล็บแรก ถ้าไม่เช่นนั้น จะได้เป็นเท็จ ทำวงเล็บสอง
ทั้งนี้ทั้งนั้น การตรวจสอบนี้ จะตรวจสอบจากค่าที่เป็น Encode แล้ว(ค่าที่คนมองเห็นแล้วรู้เรื่อง) คือ ไม่ได้ตรวจจากค่า ASCII(ค่าที่คนไม่รู้เรื่องแต่คอมอ่านออก) ดังนั้น ตัวหนังสือ จากภาษาอื่นๆ จะไม่เกี่ยว

ปล. ผมเข้าใจตามนี้นะครับ ถ้าผมอธิบายผิด ก็ช่วยแก้ให้ด้วยน๊าคร๊าบบ  ตอนนี้ก็ทำได้ตามที่คิดไว้แล้ว ยังไงก็ขอบคุณ คุณโจ้ อีกทีครับ  :'(

Dr.K

ขอบคุณมากครับ ได้อะไรเนียนๆมาอีกแระ
;D
[direct=https://www.thaihealth.net/blog/seo_doctor/]seo blog[/direct]|[direct=https://netplushost.com]netplushost[/direct]
[direct=https://pattayawebmarketing.com/pattaya-seo]pattaya seo[/direct]
[direct=https://dochost.net]seo hosting[/direct]

EThaiZone

หลักๆ จะอยู่ที่การเซฟชนิด encoding ของไฟล์นั้นๆ ด้วยครับ

อย่าลืมด้วย หุๆ  :P

Tee++;

[direct=http://laravel.in.th]Laravel in Thai[/direct]
[direct=http://jquerytips.com]jQueryTips by Tee++;[/direct]
[direct=https://www.facebook.com/jQueryTips]jQueryTips Page[/direct]
[direct=https://www.facebook.com/Laravel.in.th]Laravel in Thai Page[/direct]
[direct=https://twitter.com/Teepluss]Teepluss's Twitter[/direct]


myong1


BosnoS

อ้างถึงจาก: UnzO ใน 22 พฤศจิกายน 2007, 23:46:55
เย้ ทำได้แล้วครับ ^^  ได้รับการช่วยเหลือจาก คุณ โจ้ EthaiZone ของเรานี้เอง  ;D
เผื่อเพื่อนๆ อยากรู้นะคับ ผมจะเปิดโปงโค๊ด (พูดซ๊ะ 555)


if(preg_match("#[ก-๙]#u","$title")){
$status ="0";
}else{
$status ="1";
}


จากโค๊ดด้านบน จะได้ว่า ถ้า String ที่ตรวจสอบ มี ก-๙ คือ รวมทั้ง สระ ด้วย จะให้ค่าเป็นจริงทำวงเล็บแรก ถ้าไม่เช่นนั้น จะได้เป็นเท็จ ทำวงเล็บสอง
ทั้งนี้ทั้งนั้น การตรวจสอบนี้ จะตรวจสอบจากค่าที่เป็น Encode แล้ว(ค่าที่คนมองเห็นแล้วรู้เรื่อง) คือ ไม่ได้ตรวจจากค่า ASCII(ค่าที่คนไม่รู้เรื่องแต่คอมอ่านออก) ดังนั้น ตัวหนังสือ จากภาษาอื่นๆ จะไม่เกี่ยว

ปล. ผมเข้าใจตามนี้นะครับ ถ้าผมอธิบายผิด ก็ช่วยแก้ให้ด้วยน๊าคร๊าบบ  ตอนนี้ก็ทำได้ตามที่คิดไว้แล้ว ยังไงก็ขอบคุณ คุณโจ้ อีกทีครับ  :'(

ลองทำแล้ว ไม่ว่าจะใส่ ไทย หรือ eng ออก $status ="1"; หมดเลย

รู้สึกผมจะมีปัญหากับ editplus แน่ๆ เลย

BosnoS

สรุปแล้ว script ดีทุกอย่างเลย

ผมพลาดเอง ดันเอา ตัวแปล ไปผ่านคำสั่ง แปลงเป็น urlencode ผลลัพท์เลยเพี้ยน

hurahura

ขอบคุณมากครับ มันยอดมากเลย

แล้วทีนี้ถ้าจะเช็คจำนวนตัวอักษร จะทำยังไงครับ ถ้าคำที่ใส่เข้ามามีทั้งภาษาไทยและอังกฤษ

ball6847

เ็ห็นพูดถึง regular expression กัน ตอนผมศึกษาเรื่องนี้อยู่ผมหาโน่นหานี่มาอ่านบานเลย (แต่ยังอ่านไปได้ไม่เท่าไหร่เองง่ะ)

แต่มีเล่มนึงผมว่ามีประโยชน์ เป็น Regular Expression Pocket Referrence เป็นคู่มืออ้างอิงของ Regex น่ะแหล่ะ แถมสำหรับหลายภาษาด้วย ลองเอาไปอ่านกันดูนะ

และก็มีโปรแกรม Regex Buddy เป็นโปรแกรมที่ผมเอาไว้ทดลอง เวลาหัดใช้อ่ะ

2 อันนี้ผมแพ็ครวมกันไว้ให้แระ โหลดเอาโลด ประมาณ 8 เม็ก

http://upload.mthai.com/F1/47d29104d55e3

เรียนกันหนุกๆนะคับ
We use Ubuntu.

[direct=http://ng-seo.sourcelab.xyz/]AngularJS SEO Experimental[/direct]

EThaiZone

อ้างถึงจาก: hurahura ใน 08 มีนาคม 2008, 19:15:06
ขอบคุณมากครับ มันยอดมากเลย

แล้วทีนี้ถ้าจะเช็คจำนวนตัวอักษร จะทำยังไงครับ ถ้าคำที่ใส่เข้ามามีทั้งภาษาไทยและอังกฤษ

ไม่ใช้ strlen ล่ะครับ ??

kudjung

ถามต่อนะครับ ถ้าจะดึงข้อมูลที่อยู่ใน <body></body> ออกมาำไงครับ เพราะถ้าเจอบรรทัดใหม่มันก็ไม่ได้แล้วเช่น
<body>12345</body>อันนี้ดึงได้แต่ถ้า
<body>

12345

</body>
อันนี้ไม่ได้อะครับ

thenetxx


$txt = ' <body>

detail

</body>';

$txt = str_replace(array('\n','\r'),'',$txt);



ก็น่าจะพอมั้งคับ
Develop site but can't develop life
ASIA

ball6847

อ้างถึงจาก: kudjung ใน 12 มีนาคม 2008, 15:57:21
ถามต่อนะครับ ถ้าจะดึงข้อมูลที่อยู่ใน <body></body> ออกมาำไงครับ เพราะถ้าเจอบรรทัดใหม่มันก็ไม่ได้แล้วเช่น
<body>12345</body>อันนี้ดึงได้แต่ถ้า
<body>

12345

</body>
อันนี้ไม่ได้อะครับ


<?php

$html 
''// your html contents

$pattern "|<body>(.*)</body>|s"// mode 's' means dot (.)  matches all newline characters (\n)
preg_match$pattern $html $match );

$bodyContent $match[1];

echo 
$bodyContent;


?>



เติิม mode s เข้าไปเพื่อบอก PHP ให้นับเครื่องหมายจุด (.) กับบรรทัดใหม่ด้วย ปกติเครื่องหมายจุด . จะนับแค่ whitespace คับ แต่จะไม่นับ newline character (\n) ด้วย เติม s เข้าไปหลัง pattern ก็โอเคแล้วครับ
We use Ubuntu.

[direct=http://ng-seo.sourcelab.xyz/]AngularJS SEO Experimental[/direct]

kudjung

อ้างถึงจาก: ball6847 ใน 12 มีนาคม 2008, 19:19:10
อ้างถึงจาก: kudjung ใน 12 มีนาคม 2008, 15:57:21
ถามต่อนะครับ ถ้าจะดึงข้อมูลที่อยู่ใน <body></body> ออกมาำไงครับ เพราะถ้าเจอบรรทัดใหม่มันก็ไม่ได้แล้วเช่น
<body>12345</body>อันนี้ดึงได้แต่ถ้า
<body>

12345

</body>
อันนี้ไม่ได้อะครับ


<?php

$html 
''// your html contents

$pattern "|<body>(.*)</body>|s"// mode 's' means dot (.)  matches all newline characters (\n)
preg_match$pattern $html $match );

$bodyContent $match[1];

echo 
$bodyContent;


?>



เติิม mode s เข้าไปเพื่อบอก PHP ให้นับเครื่องหมายจุด (.) กับบรรทัดใหม่ด้วย ปกติเครื่องหมายจุด . จะนับแค่ whitespace คับ แต่จะไม่นับ newline character (\n) ด้วย เติม s เข้าไปหลัง pattern ก็โอเคแล้วครับ

โอ้ว เยี่ยมครับ ขอบคุณมากๆ เลย

hurahura

#19
อ้างถึงจาก: EThaiZone ใน 10 มีนาคม 2008, 09:01:02
อ้างถึงจาก: hurahura ใน 08 มีนาคม 2008, 19:15:06
ขอบคุณมากครับ มันยอดมากเลย

แล้วทีนี้ถ้าจะเช็คจำนวนตัวอักษร จะทำยังไงครับ ถ้าคำที่ใส่เข้ามามีทั้งภาษาไทยและอังกฤษ

ไม่ใช้ strlen ล่ะครับ ??

ถ้าเป็น ภาษาไทย UTF-8 มันนับ 3 อ่ะครับ
แต่ทำได้ละครับ ให้แปลงไปเป็น tis620 ก่อน แล้วถึงหาจำนวนตัวอักษร แล้วค่อยแปลงกลับ

function utf8totis620($string) {
  $str = $string;
  $res = "";
  for ($i = 0; $i < strlen($str); $i++) {
    if (ord($str[$i]) == 224) {
      $unicode = ord($str[$i+2]) & 0x3F;
      $unicode |= (ord($str[$i+1]) & 0x3F) << 6;
      $unicode |= (ord($str[$i]) & 0x0F) << 12;
      $res .= chr($unicode-0x0E00+0xA0);
      $i += 2;
    } else {
      $res .= $str[$i];
    }
  }
  return $res;
}

function tis2utf8($tis) {
   for( $i=0 ; $i< strlen($tis) ; $i++ ){
      $s = substr($tis, $i, 1);
      $val = ord($s);
      if( $val < 0x80 ){
         $utf8 .= $s;
      } elseif ( ( 0xA1 <= $val and $val <= 0xDA ) or ( 0xDF <= $val and $val <= 0xFB ) ){
         $unicode = 0x0E00 + $val - 0xA0;
         $utf8 .= chr( 0xE0 | ($unicode >> 12) );
         $utf8 .= chr( 0x80 | (($unicode >> 6) & 0x3F) );
         $utf8 .= chr( 0x80 | ($unicode & 0x3F) );
      }
   }
   return $utf8;
}

$name = utf8totis620($name);
echo strlen($name);
$name = tis2utf8($name);


ถ้ามีวิธีดีกว่านี้ แนะนำด้วยครับ

ปล. โค้ดแปลงไปมาระหว่าง tis620 กับ utf8 เอามาจากในเน็ต แต่จำไม่ได้เอามาจากเว็บไหน แต่ใช้ได้ผล