求基于正则的HSL/RGB颜色字符串转数组方案(弃用split)
Perfect! Since you already have the regex-based solution for RGB to array conversion, let’s focus on building the same for HSL/HSLA—no split() allowed, just pure regex magic.
HSL to Array with Regex
First, let’s break down the common HSL formats we need to handle:
- Standard HSL:
hsl(120, 50%, 50%) - HSLA (with alpha):
hsla(0, 100%, 50%, 0.8) - Formats with extra spaces:
hsl( 240 , 70% , 30% ) - Case-insensitive variants:
HSLA(...)
Step 1: The Regex Pattern
This regex will capture all the values while ignoring whitespace and handling both HSL and HSLA:
const hslRegex = /^hsla?\(\s*(\d+)\s*,\s*(\d+(?:\.\d+)?%)\s*,\s*(\d+(?:\.\d+)?%)\s*(?:,\s*(\d+(?:\.\d+)?)\s*)?\)$/i;
Let’s break down the key parts:
^hsla?$: Matches the start of the string, followed by eitherhslorhsla(case-insensitive thanks to theiflag)\(\s*: Matches the opening parenthesis, followed by any number of whitespace characters(\d+): Captures the hue value (a whole number, e.g., 120)\s*,\s*: Matches a comma surrounded by any whitespace(\d+(?:\.\d+)?%): Captures saturation/brightness values (supports integers like50%or decimals like33.3%)(?:,\s*(\d+(?:\.\d+)?)\s*)?: Optional non-capturing group for the alpha value (supports integers like1or decimals like0.7), wrapped in optional whitespace
Step 2: The Conversion Function
Now we’ll use this regex to extract values and convert them into a clean array:
function hslToArray(hslStr) { const hslRegex = /^hsla?\(\s*(\d+)\s*,\s*(\d+(?:\.\d+)?%)\s*,\s*(\d+(?:\.\d+)?%)\s*(?:,\s*(\d+(?:\.\d+)?)\s*)?\)$/i; const matches = hslStr.match(hslRegex); if (!matches) { throw new Error("Invalid HSL/HSLA color string"); } // Extract and convert each component const hue = parseInt(matches[1], 10); const saturation = parseFloat(matches[2].replace("%", "")) / 100; // Convert % to 0-1 decimal const lightness = parseFloat(matches[3].replace("%", "")) / 100; const alpha = matches[4] ? parseFloat(matches[4]) : 1; // Default alpha to 1 if missing // Return array (3 elements for HSL, 4 for HSLA) return matches[4] ? [hue, saturation, lightness, alpha] : [hue, saturation, lightness]; }
Step 3: Test It Out
Let’s run some examples to verify:
console.log(hslToArray("hsl(120, 50%, 50%)")); // Output: [120, 0.5, 0.5] console.log(hslToArray("HSLA( 0 , 100% , 50% , 0.7 )")); // Output: [0, 1, 0.5, 0.7] console.log(hslToArray("hsl(240, 75.5%, 20%)")); // Output: [240, 0.755, 0.2]
Bonus: Support for Decimal Saturation/Lightness (No %)
If you need to handle formats like hsl(120, 0.5, 0.5) (where saturation/lightness are decimals instead of percentages), tweak the regex and conversion logic like this:
function hslToArrayFlexible(hslStr) { const hslRegex = /^hsla?\(\s*(\d+)\s*,\s*(\d+(?:\.\d+)?%?)\s*,\s*(\d+(?:\.\d+)?%?)\s*(?:,\s*(\d+(?:\.\d+)?)\s*)?\)$/i; const matches = hslStr.match(hslRegex); if (!matches) { throw new Error("Invalid HSL/HSLA color string"); } const hue = parseInt(matches[1], 10); // Handle saturation (with or without %) const satValue = matches[2]; const saturation = satValue.includes("%") ? parseFloat(satValue.replace("%", "")) / 100 : parseFloat(satValue); // Handle lightness (with or without %) const lightValue = matches[3]; const lightness = lightValue.includes("%") ? parseFloat(lightValue.replace("%", "")) / 100 : parseFloat(lightValue); const alpha = matches[4] ? parseFloat(matches[4]) : 1; return matches[4] ? [hue, saturation, lightness, alpha] : [hue, saturation, lightness]; } // Test the flexible version console.log(hslToArrayFlexible("hsl(120, 0.5, 0.5)")); // Output: [120, 0.5, 0.5] console.log(hslToArrayFlexible("hsl(120, 50%, 0.3)")); // Output: [120, 0.5, 0.3]
This solution stays true to your preference of using regex exclusively—no split() in sight! 😊
内容的提问来源于stack exchange,提问作者Jose Carlos Ramos Carmenates

