๐ camelCase๋ฅผ ๋จ์ด ๋จ์๋ก ํ์ฑ ํ๊ธฐ
์ถ์ฝ ํํ(ex. CSS
)๋ ์ง์ํ๋ฉด์ ๋ค์๊ณผ ๊ฐ์ด camelCase ํค์๋๋ฅผ ๋จ์ด ๋จ์๋ก ํ์ฑ ํ๋ ค๊ณ ํฉ๋๋ค.
searchSeoulPOIItems → search seoul poi items
searchSeoulPoiItems → search seoul poi items
CSSProperties → css properties
searchNIMBUS2000BroomStick → search nimbus2000 broom stick
์ ๊ท์์ lookbehind
๋ฅผ ์ฌ์ฉํ๋ฉด ์ฝ๊ฒ ํด๊ฒฐ์ด ๊ฐ๋ฅํ๋ฐ, safari๋ 16.4๋ถํฐ ์ง์ํด์ ํฌ๋ก์ค๋ธ๋ผ์ฐ์ง ์ด์๊ฐ ์์ต๋๋ค.
๊ทธ๋์ ๋ค๋ฅธ ๋ฐฉ์์ผ๋ก ๋ฌธ์ ๋ฅผ ํด๊ฒฐํด๋ณด๋ ค๊ณ ํฉ๋๋ค.
๐ lookbehind๋ฅผ ์ฌ์ฉํ์ง ์๊ณ ํด๊ฒฐํด ๋ณด๊ธฐ
์ด์ ๋ถํฐ 2๊ฐ์ง ๊ณผ์ ์ผ๋ก ์งํ๋ฉ๋๋ค.
- ์ ๋ถ ๋๋ฌธ์๋ก ์ด๋ฃจ์ด์ง ์ถ์ฝ๋จ์ด๋ฅผ ์ถ์ถํ๊ณ ์ด๋ฅผ lowercase ๋ณํ + ๋งจ ์์ ๊ณต๋ฐฑ์ ํ๋ ์ถ๊ฐํด ์ค๋๋ค.
- ์ ๊ท์์ผ๋ก ๋๋ฌธ์+์๋ฌธ์๋ก ๊ตฌ์ฑ๋ ๊ท์น์ ์ฐพ์ ์ฒ๋ฆฌํด์ค๋๋ค.
์ด๋, 1, 2 ๋ชจ๋์์ ๋งค์นญ๋ ๋ฌธ์๋ฅผ ๋ชจ๋ ์๋ฌธ์๋ก ๋ฐ๊ฟ์ค๋๋ค.
1๏ธโฃ ๋๋ฌธ์๋ก๋ง ๊ตฌ์ฑ๋ ์ถ์ฝ์ด ์ฐพ๊ธฐ
์ถ์ฝํํ์ ํฌํจํ ๊ฒฝ์ฐ pointABC, pointABC900
์ฒ๋ผ ๋๋ฌธ์ ํน์ ์ซ์๋ก ๋๋ ์ ์์ต๋๋ค.
๋ค๋ง ์ฌ๊ธฐ์๋ ๊ฒฝ๊ณ๊ตฌ๋ถ๋ง ํด์ฃผ๋ฉด ๋๊ธฐ ๋๋ฌธ์ ๋ค์๊ณผ ๊ฐ์ ์ ๊ท์์ผ๋ก ๋จ์ด๋ฅผ ๊ตฌ๋ถํฉ๋๋ค.
([A-Z](?=[A-Z0-9])|[A-Z]$)
๊ตฌ๋ถ์ ํด์คฌ์ผ๋ ์ด์ ๊ณต๋ฐฑ์ถ๊ฐ + ์๋ฌธ์ ๋ณํ
์ ํด์ค์ผ ํฉ๋๋ค.
์ ์ ๊ท์์ผ๋ก ๋๋ฌธ์๋ก ๊ตฌ์ฑ๋ ์ฝ์์ ๋งจ ์๊ธ์์๋ง ์์ ๊ณต๋ฐฑ 1๊ฐ๋ฅผ ์ถ๊ฐํด์ค์ผ ํฉ๋๋ค.
์ด๋ฅผ ์ํด ๋งค์นญ๋ ๋ฌธ์์ offset์ ์ด์ฉํฉ๋๋ค.
์ด์ ์ ๋งค์นญ๋ ๋ฌธ์์ offset๊ณผ 2 ์ด์ ์ฐจ์ด๊ฐ ๋๋ฉด ์๋ก์ด ๋จ์ด๋ก ๊ตฌ๋ถ๋จ์ ์ ์ ์์ต๋๋ค.
function replaceShorthand(str: string) {
const replacer = createReplacer()
return str.replace(/([A-Z](?=[A-Z0-9])|[A-Z]$)/g, replacer)
}
function createReplacer() {
let prevMatchedOffset = -2 // ์ฒซ๋ฒ์งธ ๋ฌธ์๊ฐ ๋งค์นญ๋ ๊ฒฝ์ฐ์๋ ์ฌ๋ฐ๋ฅด๊ฒ ์ฒ๋ฆฌํ๊ธฐ ์ํด ์์ ๊ฒฝ๊ณ๊ฐ์ -2 ๋ก ์ค์
return (match: string, group: unknown, offset: number) => {
const offsetDiff = offset - prevMatchedOffset
const needWhiteSpace = offsetDiff > 1 && offset > 0
prevMatchedOffset = offset
const whitespace = needWhiteSpace ? ' ' : ''
return whitespace + match.toLowerCase()
}
}
prevMatchedOffset
์ด๊ธฐ๊ฐ์ด -2 ์ธ ๊ฒ์ ๋์ฌ๊ฒจ๋ด
์๋ค.
๊ทธ๋ฆฌ๊ณ ๋งค์นญ๋ ๋ฌธ์์ offset ์ด 0์ธ ๊ฒฝ์ฐ์๋ ์์ ๊ณต๋ฐฑ์ ๋ฃ์ด์ฃผ๋ฉด ์ ๋ฉ๋๋ค.
๋งค์นญ๋๋ ํจํด์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
searchSeoulPOIItems
^^^
CSSProperties
^^^
APC900
^^^
์ฌ๊ธฐ๊น์ง ํ๋ฉด ๋ค์๊ณผ ๊ฐ์ด ํ์ฑ ๋ฉ๋๋ค.
> input: searchSeoul95GuidePPLAndFood
> output: searchSeoul95Guide pplAndFood
โ ๏ธ ์ฃผ์ํ ์ฌํญ
camelCase์์ ์ถ์ฝ์ด๋ฅผ ๋๋ฌธ์๋ก ํํํ ๋๋ ์ถ์ฝ์ด๋ค์ ์ค๋ ์๋ก์ด ๋จ์ด๋ ๋๋ฌธ์๋ก ์์ํฉ๋๋ค.
๋๋ฌธ์ ๋ค์๊ณผ ๊ฐ์ด ๊ท์น์ ๋ฒ์ด๋ ๊ฒฝ์ฐ๋ ์ฌ๋ฐ๋ฅธ ๊ตฌ๋ถ์ด ์ด๋ ต์ต๋๋ค.
POPLandGoods
2๏ธโฃ ๋๋ฌธ์+์๋ฌธ์๋ก
๊ตฌ์ฑ๋ ๊ท์น ์ฒ๋ฆฌํ๊ธฐ
์ ๊ท์์ผ๋ก ๋๋ฌธ์+์๋ฌธ์ n๊ฐ (ex. Camel
) ๋ก ๊ตฌ์ฑ๋ ๋จ์ด๋ฅผ ๊ตฌ๋ถํฉ๋๋ค.
([A-Z](?=[a-z0-9]))
์ด์ ํด๋น ๋จ์ด์ ๋งค์นญ๋๋ ๋ถ๋ถ์ replace ์ฒ๋ฆฌํฉ๋๋ค. ๋คํํ๋, ์ด์ ์ ์ฐ๋ฆฌ๊ฐ ๊ตฌํํ replacer๋ก ๋์ผํ ์ฒ๋ฆฌ๊ฐ ๊ฐ๋ฅํฉ๋๋ค.
replacer๊ฐ ๋ชจ๋ ๋๋ฌธ์๋ฅผ ์๋ฌธ์๋ก ๋ฐ๊พธ๋ ์ฐ์๋ ๋๋ฌธ์๋ผ๋ฉด ์ฒซ ๋ฒ์งธ ๋๋ฌธ์ ์์๋ง ๊ณต๋ฐฑ์ ์ถ๊ฐํด ์ฃผ๊ธฐ ๋๋ฌธ์
๋๋ค.
๊ทธ๋์ createReplacer๋ฅผ ๊ทธ๋๋ก ํ์ฉํด ์ค๋๋ค.
function replaceCapitalLetter(str: string) {
const replacer = createReplacer()
return str.replace(/([A-Z](?=[a-z0-9]))/g, replacer)
}
์ฌ๊ธฐ์ ๋งค์นญ๋๋ ํจํด์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
searchA9Seoul poiItems
^ ^ ^
searchSeoulPoiItems
^ ^ ^
cssProperties
^
C9
^
๐ ์์์ ๊ตฌํํ ํจ์๋ค์ ํฉ์นฉ๋๋ค.
1๋ฒ๊ณผ 2๋ฒ์์ ๊ตฌํํ ํจ์๋ค์ ์ฌ์ฉํ๋ parse
๋ผ๋ ํจ์๋ฅผ ๊ตฌํํฉ๋๋ค.
ํ์ฑ ํ ๋ฌธ์์ด์ ์ธ์๋ก ๋ฐ๊ณ ์ถ์ฝ์ด ํ์ฑ
๊ณผ ๋๋ฌธ์ ํ์ฑ
๊ณผ์ ์ ๊ฑฐ์ณ์ ์ต์ข
๋ฌธ์์ด์ด ์์ฑ๋ฉ๋๋ค.
function parse(str: string) {
const sanitized = replaceShorthand(str)
const pretty = replaceCapitalLetter(sanitized)
return pretty
}
parse
ํจ์๋ฅผ ์ฌ์ฉํ๋ฉด ๋ค์๊ณผ ๊ฐ์ ๊ฒฐ๊ณผ๋ฅผ ์ป์ ์ ์์ต๋๋ค.
input: searchSeoulGuide
output: search seoul guide
input: searchSeoul95GuidePPLAndFood
output: search seoul95 guide ppl and food
'๐จโ๐ป web.dev > fe' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
Chrome ๊ฐ๋ฐ์๋๊ตฌ๋ฅผ ์ด์ฉํด์ ์์น์ ๋ณด ์ค์ ํ๊ธฐ (0) | 2024.03.01 |
---|---|
storybook middleware proxy ๋ก CORS ์ฐํํ๊ธฐ (0) | 2024.03.01 |
rAF ํ๋ ์ ๋น์จ ์กฐ์ ํ๊ธฐ (0) | 2024.01.30 |
point-in-polygon ์๊ณ ๋ฆฌ์ฆ์ผ๋ก ๊ตญ๋ด์ธ ํ๋จํ๊ธฐ (0) | 2024.01.30 |
Vanilla JS ๋ก FigJam ์น์ฑ ๋ง๋ค๊ธฐ (1) | 2024.01.23 |
๐ฌ ๋๊ธ