RegExp.prototype.toString() คืออะไร?
คืนค่า String representation ของ Regular Expression object ในรูปแบบ Literal notation: /pattern/flags
- ใช้สำหรับ Debugging, Logging, Display pattern ให้ผู้ใช้เห็น
- คืนค่า string ที่เป็น valid RegExp literal เสมอ
- Escape special characters อัตโนมัติ
ตัวอย่างโค้ดครบถ้วน
<!DOCTYPE html>
<html lang="th">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>RegExp toString() Demo</title>
<style>
body { font-family: 'Segoe UI', sans-serif; padding: 20px; max-width: 800px; margin: 0 auto; }
.panel { background: #f5f5f5; padding: 20px; border-radius: 8px; margin-bottom: 20px; }
.code { background: #2d2d2d; color: #f8f8f2; padding: 15px; border-radius: 4px; font-family: monospace; overflow-x: auto; }
.output { background: #e8f5e9; padding: 15px; border-radius: 4px; font-family: monospace; white-space: pre-wrap; }
button { padding: 10px 20px; background: #7e32d4; color: white; border: none; border-radius: 4px; cursor: pointer; margin-right: 10px; margin-bottom: 10px; }
button:hover { background: #6a1b9a; }
table { width: 100%; border-collapse: collapse; margin-top: 10px; }
th, td { padding: 10px; border: 1px solid #ddd; text-align: left; }
th { background: #7e32d4; color: white; }
.regex-display { font-family: monospace; background: #fff3e0; padding: 2px 6px; border-radius: 3px; }
</style>
</head>
<body>
<h1>RegExp.prototype.toString()</h1>
<p>แปลง Regular Expression object เป็น String literal format</p>
<div class="panel">
<h3>ทดสอบ RegExp ต่างๆ</h3>
<button onclick="testBasic()">Basic Patterns</button>
<button onclick="testFlags()">Flags (g, i, m, s, u, y)</button>
<button onclick="testSpecialChars()">Special Characters</button>
<button onclick="testConstructors()">Constructor vs Literal</button>
</div>
<div class="panel">
<h3>ผลลัพธ์</h3>
<div class="output" id="output"></div>
</div>
<script>
const output = document.getElementById('output');
function log(msg) {
output.textContent += msg + '\n';
}
function clear() { output.textContent = ''; }
function testBasic() {
clear();
const patterns = [
/hello/,
/hello world/,
/\d+/,
/\w+/,
/[a-z]+/,
/^.+$/
];
patterns.forEach(re => {
log(`Regex: ${re} → toString(): ${re.toString()}`);
});
}
function testFlags() {
clear();
const basePattern = 'test';
const flags = ['', 'g', 'i', 'm', 'gi', 'gim', 's', 'u', 'y'];
flags.forEach(flag => {
const re = new RegExp(basePattern, flag);
log(`new RegExp('${basePattern}', '${flag}') → ${re.toString()}`);
});
log('\n--- Combined flags ---');
log(`new RegExp('abc', 'gimu') → ${new RegExp('abc', 'gimu').toString()}`);
}
function testSpecialChars() {
clear();
// ตัวอักษรพิเศษที่ต้อง escape ใน regex
const specials = ['*', '+', '?', '^', '$', '.', '|', '(', ')', '[', ']', '{', '}', '\\', '/'];
specials.forEach(char => {
const re = new RegExp(char);
log(`Char: "${char}" → Regex: ${re.toString()}`);
});
log('\n--- Escaped in pattern ---');
const re = /a\/b\?c\*d/;
log(`Literal: /a\\/b\\?c\\*d/ → toString(): ${re.toString()}`);
}
function testConstructors() {
clear();
// Constructor pattern (string) vs Literal
const strPattern = 'hello\\sworld';
const re1 = new RegExp(strPattern); // จาก string
const re2 = /hello\sworld/; // literal
log(`String pattern: "${strPattern}"`);
log(`new RegExp(pattern) → ${re1.toString()}`);
log(`Literal /hello\\\\sworld/ → ${re2.toString()}`);
log(`Are they equal? ${re1.toString() === re2.toString()}`);
log('\n--- With flags ---');
const re3 = new RegExp(strPattern, 'gi');
const re4 = /hello\sworld/gi;
log(`new RegExp(pattern, 'gi') → ${re3.toString()}`);
log(`Literal /hello\\\\sworld/gi → ${re4.toString()}`);
}
</script>
</body>
</html>
ผลลัพธ์ตัวอย่าง
Regex: /hello/ → toString(): /hello/
Regex: /hello world/ → toString(): /hello world/
Regex: /\d+/ → toString(): /\d+/
Regex: /[a-z]+/ → toString(): /[a-z]+/
Regex: /^.+$/ → toString(): /^.+$/
new RegExp('test', 'g') → /test/g
new RegExp('test', 'i') → /test/i
new RegExp('test', 'gi') → /test/gi
new RegExp('test', 'gimu') → /test/gimu
Char: "*" → Regex: /\*/
Char: "?" → Regex: /\?/
Char: "/" → Regex: /\// (slash ต้อง escape ใน literal)
Literal: /a\/b\?c\*d/ → toString(): /a\/b\?c\*d/
RegExp Flags ใคร่รู้จัก
| Flag | ชื่อ | คำอธิบาย |
g | Global | หาทุก match ใน string (ไม่หยุดที่ match แรก) |
i | Ignore Case | ไม่สนใจตัวพิมพ์ใหญ่/เล็ก |
m | Multiline | ^ และ $ match ทุกบรรทัด |
s | DotAll | . match newline ด้วย (ES2018) |
u | Unicode | รองรับ Unicode code points (ES2015) |
y | Sticky | Match ต้องเริ่มที่ lastIndex เท่านั้น (ES2015) |
d | Indices | คืนค่า indices ของ match (ES2022) |
การใช้งานจริง
1. Debugging / Logging
function logRegex(regex) {
console.log(`Pattern: ${regex.toString()}`);
console.log(`Source: ${regex.source}`);
console.log(`Flags: ${regex.flags}`);
}
2. Dynamic Regex Construction
function buildSearchRegex(query, options = {}) {
const flags = [
options.global ? 'g' : '',
options.ignoreCase ? 'i' : '',
options.multiline ? 'm' : ''
].join('');
// Escape special regex chars in user input
const escaped = query.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
const regex = new RegExp(escaped, flags);
console.log('Created regex:', regex.toString());
return regex;
}
3. Serialize/Store Regex
// บันทึกลง localStorage / Database
const patterns = [
{ name: 'email', regex: /^[^\s@]+@[^\s@]+\.[^\s@]+$/ },
{ name: 'phone', regex: /^\+?[\d\s-]{10,}$/ }
];
const serialized = patterns.map(p => ({
name: p.name,
pattern: p.regex.source,
flags: p.regex.flags
}));
// นำกลับมาใช้
const restored = serialized.map(p => new RegExp(p.pattern, p.flags));
ความแตกต่าง: toString() vs source vs flags
| Property/Method | คืนค่า | ตัวอย่าง |
regex.toString() | Full literal string | "/hello/gi" |
regex.source | Pattern only (no slashes, no flags) | "hello" |
regex.flags | Flags only | "gi" |