feat(comment-cards): 유튜브 videoId 파서 추가
watch/youtu.be/shorts/embed/순수ID 추출, 단위 테스트 포함 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
4776905745
commit
39e2b42995
@ -0,0 +1,30 @@
|
||||
package com.hlab.yanalyst.service;
|
||||
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.regex.Matcher;
|
||||
|
||||
/** 유튜브 URL 또는 11자리 영상 ID에서 videoId를 추출한다. 실패 시 null. */
|
||||
public final class YoutubeVideoIdParser {
|
||||
|
||||
private static final Pattern BARE = Pattern.compile("^[A-Za-z0-9_-]{11}$");
|
||||
private static final Pattern[] PATTERNS = {
|
||||
Pattern.compile("[?&]v=([A-Za-z0-9_-]{11})"),
|
||||
Pattern.compile("youtu\\.be/([A-Za-z0-9_-]{11})"),
|
||||
Pattern.compile("/shorts/([A-Za-z0-9_-]{11})"),
|
||||
Pattern.compile("/embed/([A-Za-z0-9_-]{11})"),
|
||||
};
|
||||
|
||||
private YoutubeVideoIdParser() {}
|
||||
|
||||
public static String parse(String input) {
|
||||
if (input == null) return null;
|
||||
String s = input.trim();
|
||||
if (s.isEmpty()) return null;
|
||||
if (BARE.matcher(s).matches()) return s;
|
||||
for (Pattern p : PATTERNS) {
|
||||
Matcher m = p.matcher(s);
|
||||
if (m.find()) return m.group(1);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,43 @@
|
||||
package com.hlab.yanalyst.service;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
class YoutubeVideoIdParserTest {
|
||||
|
||||
@Test
|
||||
void parsesWatchUrl() {
|
||||
assertEquals("dQw4w9WgXcQ",
|
||||
YoutubeVideoIdParser.parse("https://www.youtube.com/watch?v=dQw4w9WgXcQ"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void parsesWatchUrlWithExtraParams() {
|
||||
assertEquals("dQw4w9WgXcQ",
|
||||
YoutubeVideoIdParser.parse("https://www.youtube.com/watch?v=dQw4w9WgXcQ&t=42s&list=ABC"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void parsesShortLink() {
|
||||
assertEquals("dQw4w9WgXcQ",
|
||||
YoutubeVideoIdParser.parse("https://youtu.be/dQw4w9WgXcQ?si=xyz"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void parsesShortsLink() {
|
||||
assertEquals("abc12345678",
|
||||
YoutubeVideoIdParser.parse("https://www.youtube.com/shorts/abc12345678"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void parsesBareId() {
|
||||
assertEquals("dQw4w9WgXcQ", YoutubeVideoIdParser.parse("dQw4w9WgXcQ"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void returnsNullForGarbage() {
|
||||
assertNull(YoutubeVideoIdParser.parse("not a youtube link"));
|
||||
assertNull(YoutubeVideoIdParser.parse(""));
|
||||
assertNull(YoutubeVideoIdParser.parse(null));
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user