รายละเอียดของการตอบ ::
จากโค้ด ตาม คำถาม regex จะสะดวกกว่า ครับ
ถึงแม้มันจะยาก แต่ถ้าได้เรียนรู้ จะเห็นว่า มันลดการผิดพลาดของโค้ด แบบ string ลงเยอะมาก
สัญลักษณ์ ความหมาย
. ทุกตัวอักษรยกเว้นการขึ้นบรรทัดใหม่
\w ทุกๆ ตัวอักษรและ underscore
\W ที่ไม่ใช่ตัวอักษร
\d ตัวเลขทุกตัว
\D ที่ไม่ใช่ตัวเลข
\s whitespace(tab, space, line break)
\S ที่ไม่ใช่ whitespace
[abc] a, b หรือ c อย่างใดอย่างหนึ่ง
[^abc] อะไรก็ได้ที่ไม่ใช่ a,b หรือ c
[a-f] อะไรก็ได้ระหว่าง a ถึง f
^ เริ่มต้น line
$ สิ้นสุด line
\A เริ่มต้นคำ
\z สิ้นสุดคำ
(…) capture group
\1 reference group #1
(a b)
a* ไม่มี a หรือมีก็ได้
a+ a อย่างน้อย 1 ตัว
a? ไม่มี a หรือมี a ได้แค่ 1ตัว
a{5} มี a 5 ตัว
a{2,5} มี a ได้ 2 ถึง 5 ตัว
https://devahoy.com/posts/regular-expressions-101/
ผมเองก็ไม่ถนัด regex แต่เห็นว่ามันเร็วและ ลดโค้ดลงได้ ในที่นี้ จะขอพูดแค่เท่าที่ผมรู้นะครับ
regex เริ่มจาก แพทเทิร์น ของ ข้อความที่ต้อง การเช่น
"(Box\s{0,}G\d{1,}/\d{1,}\s{0,}\d{1,}/\d{1,})"
จากข้อความที่ต้องการเช่น
Code
สอบถามเรื่องการตัดคำครับ ผมจะตัดคำที่รับ ค่ามาเป็น string แล้ว ผมตัดคำจะเอาเฉพาะตัวเลขครับ แต่ว่าผมใช้การตัดโดยใช้คำสั่ง mid แต่ติดตรงที่ว่าตำแหน่งมันจะเลื่อนไปครับ ตามหลักของตัวเลข (โปรแกรมอ่านค่าจาก textfile)
format ผม จะประมาณนี้ครับ
สแกนยังไม่ครบ Box G1709/02911 6/504 10/31/2017 2:27:27 PM
สแกนยังไม่ครบ Box G1709/02918 60/504 10/31/2017 2:27:56 PM
สแกนยังไม่ครบ Box G1709/02921 108/504 10/31/2017 2:27:56 PM
ผมใช้การตัดคำโดยแบ่งเป็นแบบนี้ครับ ตามสี วันที่เวลาผมตัดทิ้งไปครับ ไม่ต้องการ แต่ว่า เลข ข้างหน้าที่เป้นสีส้ม เป็นหลัก หน่วย สิบ ร้อย ผมไม่สามารถกำหนดที่ให้มันตัดคำได้ตรงตามต้องการครับ ส่วนเลขข้างหลังสีนํ้าเงินผมสามารถกำหนดได้แล้วครับ สีส้มจะแสดงผลแบบนี้ครับ
regex ไม่สนใจว่าข้อความที่อยากได้อยู่บรรทัดไหน สนใจแค่มันตรงกับ แพทเทิร์นรึไม่
"(Box\s{0,}G\d{1,}/\d{1,}\s{0,}\d{1,}/\d{1,})"
\s{0,} => space ตั้งแต่ 0 ตัว ขึ้นไป ดังจะเห็นว่าใช้ {0,} แทนการบอกว่า 0 ตัวขึ้นไป
\d{1,} =>ตัวเลข(0-9) ตั้งแต่ 1 ตัว ขึ้นไป ดังจะเห็นว่าใช้ {1,} แทนการบอกว่า 1 ตัวขึ้นไป
ในกรณีที่จำนวนตายตัวก็ใช้ \d{5} แทนว่าต้องมีตัวเลข 5 ตัวเท่านั้น และใช้ \d{2,5} เพื่อแทนว่าต้องมีตัวเลข 2 - 5 ครับ
ค่าที่ได้จะออกมาเป็น
array เราก็แค่ for loop ไปใช้งาน แค่นั้นครับ
( ) คือค่าที่เราอยากได้
เช่น
มาจาก
"Box\s{0,}G\d{1,}/\d{1,}\s{0,}(\d{1,}/\d{1,})"
แต่ถ้า
มาจาก
"(Box\s{0,}G\d{1,}/\d{1,}\s{0,}\d{1,}/\d{1,})"
และก็
มาจาก
"(Box\s{0,}G\d{1,}/\d{1,})\s{0,}(\d{1,}/\d{1,})"
จะเห็นได้ว่าลูกเล่นจะเยอะกว่า string ที่เราเคยใช้กัน และก็แยกข้อความได้แม่นยำกว่า เพราะไม่ต้องสนใจเรื่อง
substring indexof trim replace อีกด้วย ครับ