Flags change the global behavior of a regex. The case-insensitive flag i makes letter matching ignore case, so /hello/i matches Hello, HELLO, and hElLo. In Unicode-aware engines the flag also applies cross-script case folding, so it can match Straße against STRASSE. The multiline flag m changes only the behavior of the anchors ^ and $, making them match at the start and end of each line rather than only at the boundaries of the whole string. It does not change how the dot . behaves, which is the role of the s (dotall) flag. In JavaScript the g flag tells methods like String.prototype.match, matchAll, and replace to iterate every match instead of stopping at the first.
The verbose or extended mode, written x in PCRE and Python, lets you format a pattern with whitespace and # comments for readability. In verbose mode, whitespace inside the pattern is ignored unless it is escaped or appears inside a character class. This is invaluable for complex patterns like the IPv4 octet rule, where breaking the expression across multiple lines with comments can transform an unreadable string into a self-documenting specification. Inline flags let you scope a flag to a subexpression. The empty non-capturing group (?:) serves as a delimiter: (?i:abc) turns on case-insensitivity for abc only, while (?-i) turns it off again. This is useful when a global flag would over-match, for example when matching an identifier case-insensitively but wanting the trailing whitespace to be matched strictly.
Language-specific features fill the gaps that the core regex standard leaves open. In Python, the re module provides re.compile for precompiling patterns used many times, re.search for finding a match anywhere in the string, and re.match for anchoring the pattern at the start of the string (equivalent to prepending \A). The function re.sub performs replacements with backreference support and accepts a callable replacement for dynamic substitutions. JavaScript's String.prototype.replace callback receives (match, ...captures, offset, fullString), which makes it easy to reorder captured groups. PCRE adds a few escapes worth knowing: \K resets the start of the reported match to the current position, useful for replacing only the tail of a match; \R matches any Unicode line break sequence including U+2028 and U+2029; and conditional subpatterns like (?(1)yes|no) branch on whether a captured group matched.