You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SQL中使用REGEX_EXTRACT提取括号内特定模式的方法咨询

Fixing REGEX_EXTRACT to Extract All [xx-XX] Patterns in SQL

Alright, let's break down how to solve your regex extraction issue. Your current formula only grabs the first bracketed string because REGEX_EXTRACT (in most SQL engines) returns just the first match by default, plus it doesn't restrict the content inside the brackets to your specific [xx-XX] pattern. Here's how to fix both problems:

Step 1: Refine the Regex to Target Your Exact Pattern

First, update your regular expression to only match brackets containing two letters, a hyphen, then two more letters (any case, since you said x represents any English letter). The refined regex is:

r'\[([A-Za-z]{2}-[A-Za-z]{2})\]'

Let's break this down:

  • \[ / \]: Escape the literal square brackets (since they're special characters in regex)
  • ([A-Za-z]{2}-[A-Za-z]{2}): A capture group that matches:
    • [A-Za-z]{2}: Exactly 2 uppercase or lowercase English letters
    • -: The literal hyphen
    • [A-Za-z]{2}: Another 2 letters

Step 2: Extract All Matches (Not Just the First)

The approach here depends on which SQL engine you're using—different tools have different functions for global regex matching:

For BigQuery

Use REGEX_EXTRACT_ALL instead of REGEX_EXTRACT to get all matching patterns as an array:

SELECT REGEX_EXTRACT_ALL(your_column_name, r'\[([A-Za-z]{2}-[A-Za-z]{2})\]') AS extracted_patterns
FROM your_table;

Example output for a cell like Hello [ab-CD] world [xy-ZW] test:
['ab-CD', 'xy-ZW']

For PostgreSQL

Use regexp_matches with the g (global) flag to return all matches. This returns each match as a row; wrap it in array_agg if you want results in a single array:

-- Return each match as a separate row
SELECT regexp_matches(your_column_name, '\[([A-Za-z]{2}-[A-Za-z]{2})\]', 'g') AS extracted_patterns
FROM your_table;

-- Return all matches as a single array per row
SELECT array_agg(match) AS extracted_patterns
FROM your_table, regexp_matches(your_column_name, '\[([A-Za-z]{2}-[A-Za-z]{2})\]', 'g') AS match;

For MySQL 8.0+

MySQL doesn't have a built-in global extract function, but you can use a recursive CTE to pull all matches, or use REGEXP_REPLACE to isolate matches then split them:

-- Option 1: Recursive CTE to extract all matches
WITH RECURSIVE extract_matches AS (
  SELECT 
    your_column_name AS original_text,
    REGEXP_SUBSTR(your_column_name, '\[([A-Za-z]{2}-[A-Za-z]{2})\]') AS matched,
    1 AS match_number
  FROM your_table
  WHERE REGEXP_SUBSTR(your_column_name, '\[([A-Za-z]{2}-[A-Za-z]{2})\]') IS NOT NULL
  UNION ALL
  SELECT
    original_text,
    REGEXP_SUBSTR(original_text, '\[([A-Za-z]{2}-[A-Za-z]{2})\]', 1, match_number + 1),
    match_number + 1
  FROM extract_matches
  WHERE REGEXP_SUBSTR(original_text, '\[([A-Za-z]{2}-[A-Za-z]{2})\]', 1, match_number + 1) IS NOT NULL
)
SELECT original_text, GROUP_CONCAT(matched) AS extracted_patterns
FROM extract_matches
GROUP BY original_text;

If You Only Need the First Valid [xx-XX] Pattern

If you don't need all matches, just the first one that fits your [xx-XX] format, use your original REGEX_EXTRACT with the refined regex:

SELECT REGEX_EXTRACT(your_column_name, r'\[([A-Za-z]{2}-[A-Za-z]{2})\]') AS first_valid_pattern
FROM your_table;

This will skip any bracketed content that doesn't match xx-XX and grab the first one that does.

内容的提问来源于stack exchange,提问作者nd12y

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.28 23:12:40