Skip to main content
EN

Home / Blog / Rules & Routing

Regex for automatic node grouping — filter and exclude-filter in practice

Rules & Routing2026-05-241304 words3 min read
Regex for automatic node grouping — filter and exclude-filter in practice

A subscription with a hundred-odd nodes makes hand-written group membership impractical, and it breaks the moment the subscription updates.

Mihomo's include-all plus filter lets a group collect matching nodes automatically — getting the regex right is the whole trick.

The basics

proxy-groups:
  - name: "🇭🇰 Hong Kong"
    type: url-test
    include-all: true                         # take everything in
    filter: "(?i)HK|Hong ?Kong"               # keep only what matches
    exclude-filter: "(?i)remaining|expire|website"   # then drop these
    url: http://www.gstatic.com/generate_204
    interval: 300
    tolerance: 50

Order of operations: include-all collects everything → filter keeps the matches → exclude-filter removes from those.

The three include options

OptionWhat it takes in
include-all: trueThe proxies section plus every proxy-provider
include-all-proxies: trueOnly nodes written by hand in proxies
include-all-providers: trueOnly nodes from providers
use: [provider name]The named providers

When your own servers live in proxies and subscription nodes come from a provider, these options give you precise control over which nodes land in which group.

Regex basics (enough to get by)

These few symbols are all you need(?i)ignore case, written at the front. Matches both HK and hkthe pipeor. "TokyoJP" matches either?the preceding character is optional. "Hong ?Kong" matches HongKong and Hong Kong^ and $start and end. "^HK" matches only names starting with HK[]a character set. "[0-9]" matches any digit\\dshorthand for a digit, equivalent to [0-9]

Grouping by region

The most common need. Cover the various names each region goes by:

# Hong Kong
filter: "(?i)HK|Hong ?Kong|HKG|🇭🇰"

# Taiwan
filter: "(?i)TW|Taiwan|Taipei|TPE|🇹🇼"

# Japan
filter: "(?i)JP|Japan|Tokyo|Osaka|🇯🇵"

# Singapore
filter: "(?i)SG|Singapore|🇸🇬"

# United States
filter: "(?i)US|USA|United ?States|Los ?Angeles|San ?Jose|Seattle|🇺🇸"

# South Korea
filter: "(?i)KR|Korea|Seoul|🇰🇷"

# United Kingdom
filter: "(?i)UK|United ?Kingdom|London|🇬🇧"

Filtering by multiplier

Many subscriptions mark a traffic multiplier in the node name (0.5x, 1x, 3x).

# only low multipliers (saving data)
filter: "(?i)0\\.[0-9]x|1x|1\\.0x"

# exclude high multipliers
exclude-filter: "(?i)[2-9](\\.[0-9])?x|1[0-9]x"

# only nodes marked as dedicated lines (usually the best quality)
filter: "(?i)IPLC|IEPL|dedicated|premium"

Excluding pseudo-nodes

Entries like "Remaining: 128 GB" or "Expires in: 30 days" are information stuffed into node names for display; they are not real nodes.

exclude-filter: "(?i)remaining|expire|expired|traffic|reset|website|subscription|url|group|announcement|backup|test|GB|Days?"

Filtering by protocol

# only Hysteria2 (for low-latency work)
filter: "(?i)hy2|hysteria"

# exclude certain protocols (Mihomo has a dedicated field, which is more reliable)
exclude-type: "ss|ssr|http"

exclude-type filters by the actual protocol type, far more dependable than guessing from a node's name.

Combining conditions

Regex is awkward at expressing "and", but two layers of filtering achieve it:

# Hong Kong and low multiplier
- name: "🇭🇰 Hong Kong low-rate"
  type: url-test
  include-all: true
  filter: "(?i)HK|Hong ?Kong"
  exclude-filter: "(?i)[2-9](\\.[0-9])?x|remaining|expire"
  interval: 300

filter narrows to Hong Kong, then exclude-filter removes high multipliers and pseudo-nodes.

For genuinely complex "and" logic, regex lookahead works:

# contains both "Hong Kong" and "IPLC"
filter: "(?i)(?=.*Hong ?Kong)(?=.*IPLC).*"

Avoid it where you can — readability suffers badly and maintenance becomes painful.

A complete template

proxy-providers:
  main:
    type: http
    url: "your subscription URL"
    interval: 3600
    path: ./providers/main.yaml
    header: { User-Agent: ["clash.meta"] }
    exclude-filter: "(?i)remaining|expire|expired|traffic|reset|website|subscription|group|announcement|backup"
    health-check: { enable: true, url: http://www.gstatic.com/generate_204, interval: 300, lazy: true }

proxy-groups:
  # master switch
  - name: "🚀 Select"
    type: select
    proxies: ["♻️ Auto", "🇭🇰 Hong Kong", "🇯🇵 Japan", "🇸🇬 Singapore", "🇺🇸 US", "🇹🇼 Taiwan", "💎 Dedicated", DIRECT]

  # global automatic
  - name: "♻️ Auto"
    type: url-test
    use: [main]
    url: http://www.gstatic.com/generate_204
    interval: 300
    tolerance: 50
    lazy: true

  # regional groups
  - name: "🇭🇰 Hong Kong"
    type: url-test
    use: [main]
    filter: "(?i)HK|Hong ?Kong|🇭🇰"
    interval: 300
    tolerance: 50
  - name: "🇯🇵 Japan"
    type: url-test
    use: [main]
    filter: "(?i)JP|Japan|Tokyo|Osaka|🇯🇵"
    interval: 300
    tolerance: 50
  - name: "🇸🇬 Singapore"
    type: url-test
    use: [main]
    filter: "(?i)SG|Singapore|🇸🇬"
    interval: 300
    tolerance: 50
  - name: "🇺🇸 US"
    type: url-test
    use: [main]
    filter: "(?i)US|USA|United ?States|Los ?Angeles|San ?Jose|🇺🇸"
    interval: 300
    tolerance: 50
  - name: "🇹🇼 Taiwan"
    type: url-test
    use: [main]
    filter: "(?i)TW|Taiwan|Taipei|🇹🇼"
    interval: 300
    tolerance: 50

  # dedicated lines (the best quality, for gaming and video)
  - name: "💎 Dedicated"
    type: fallback
    use: [main]
    filter: "(?i)IPLC|IEPL|dedicated|premium"
    interval: 600

  # by purpose
  - name: "🤖 AI services"
    type: select
    proxies: ["🇺🇸 US", "🇯🇵 Japan", "🇸🇬 Singapore", "🚀 Select"]
  - name: "🎬 Streaming"
    type: select
    proxies: ["🇭🇰 Hong Kong", "🇸🇬 Singapore", "💎 Dedicated", "🚀 Select"]
  - name: "🎮 Gaming"
    type: select
    proxies: ["💎 Dedicated", "🇭🇰 Hong Kong", "🇯🇵 Japan"]
  - name: "🐟 Fallthrough"
    type: select
    proxies: ["🚀 Select", DIRECT]

Verifying that a filter is right

The verification loopSave the config and reloadclick reload in the clientOpen the proxies pagefind the group you wroteCount the nodesdoes it match what you expectedRead the node nameshas anything unwanted crept in
An empty group means the filter is too strict, or simply wrong

The group is empty — check in order:

  1. Is there a typo in the regex (watch for stray spaces in node names)
  2. Did you forget (?i) while the node names are lowercase hk
  3. Is exclude-filter too broad, removing what you wanted
  4. Did the provider named in use load successfully

Unwanted nodes crept in:

Add a distinctive word from that node's name to exclude-filter, or make filter more precise by anchoring with ^ or $.

Common traps

Where things go wrongForgetting (?i) — a case mismatch is the most common causeFiltering on a two-letter fragment (US, SG, JP) — it overreaches, so anchor it or spell the name outNo spaces around the pipe — "Hong KongHK" folds the spaces into the matchFull-width spaces in node names — not the same character as an ordinary spaceA dot in a regex matches any character — a multiplier like 0.5x must be escaped as 0\\.5xEmoji match too — some subscriptions use flag emoji rather than words

When not to use filter

With few nodes (a dozen or so), irregular names, or when you want total control over each group's contents, writing node names by hand is perfectly fine:

- name: "🇭🇰 Hong Kong"
  type: url-test
  proxies:
    - "Hong Kong IPLC 01"
    - "Hong Kong BGP 02"
  interval: 300

The price is that new nodes appearing after a subscription update do not join automatically and need maintaining by hand.

In short

  • (?i) is needed almost every time
  • Do not use a two-letter fragment as a filter word on its own — it overreaches
  • Exclude pseudo-nodes once at the provider level rather than in every group
  • exclude-type beats guessing the protocol from a name
  • After writing one, always count the nodes on the proxies page to verify
  • Give dedicated lines their own fallback group for gaming and video

Related: the five proxy-group types and managing several subscriptions.


Related docs