특정 키워드가있는 하위 문자열 추출기
도전
이 과제의 목표는 입력 문자열, 시작 키워드 및 종료 키워드를받는 함수를 만드는 것입니다. 추출 된 출력 결과는 지정된 시작 키워드에서 (그러나 제외됨) 종료 키워드까지입니다. 출력 하위 문자열은 아래와 같은 규칙을 따릅니다.
모든 경우에 출력 하위 문자열의 선행 / 후행 공백을 제거해야합니다.
주어진 시작 키워드가 빈 문자열이면 앵커가 입력 문자열의 시작에 있음을 의미합니다. 그렇지 않으면 주어진 시작 키워드의 첫 번째 발생이 시작 앵커입니다. 주어진 시작 키워드의 발생이 없으면 출력은 빈 문자열입니다.
주어진 end 키워드가 빈 문자열이면 앵커가 입력 문자열의 끝에 있음을 의미합니다. 그렇지 않으면 주어진 end 키워드의 첫 번째 발생은 끝 앵커입니다. 주어진 end 키워드가 없으면 출력은 빈 문자열입니다.
시작 앵커의 위치가 끝 앵커의 위치 이후이거나 지정된 시작 키워드의 첫 번째 발생 부분과 지정된 끝 키워드의 첫 번째 발생 부분이 겹치는 경우 출력은 빈 문자열입니다.
비슷하지만 주어진 문자열에서 문자열 추출과는 다르지만 지정된 시작 및 끝 앵커는 여러 문자입니다.
다음은 C #의 ungolfed 참조 구현입니다.
private static string GetTargetString(string stringInput, string startKeywordInput, string endKeywordInput)
{
int startIndex;
if (String.IsNullOrEmpty(startKeywordInput))
{
startIndex = 0;
}
else
{
if (stringInput.IndexOf(startKeywordInput) >= 0)
{
startIndex = stringInput.IndexOf(startKeywordInput) + startKeywordInput.Length;
}
else
{
return "";
}
}
int endIndex;
if (String.IsNullOrEmpty(endKeywordInput))
{
endIndex = stringInput.Length;
}
else
{
if (stringInput.IndexOf(endKeywordInput) > startIndex)
{
endIndex = stringInput.IndexOf(endKeywordInput);
}
else
{
return "";
}
}
// Check startIndex and endIndex
if (startIndex < 0 || endIndex < 0 || startIndex >= endIndex)
{
return "";
}
if (endIndex.Equals(0).Equals(true))
{
endIndex = stringInput.Length;
}
int TargetStringLength = endIndex - startIndex;
return stringInput.Substring(startIndex, TargetStringLength).Trim();
}
입력 및 출력 예
예제 입력 및 출력은 다음과 같습니다.
입력 문자열 | 시작 키워드 | 끝 키워드 | 산출 |
---|---|---|---|
"C #은 Microsoft가 .NET 이니셔티브의 일부로 2000 년경에 개발했습니다." | ""(빈 문자열) | ""(빈 문자열) | "C #은 Microsoft가 .NET 이니셔티브의 일부로 2000 년경에 개발했습니다." |
"C #은 Microsoft가 .NET 이니셔티브의 일부로 2000 년경에 개발했습니다." | ""(빈 문자열) | ".그물" | "C #은 Microsoft에서 2000 년경에 개발되었습니다." |
"C #은 Microsoft가 .NET 이니셔티브의 일부로 2000 년경에 개발했습니다." | "씨#" | ""(빈 문자열) | "Microsoft는 .NET 이니셔티브의 일부로 2000 년경에 개발했습니다." |
"C #은 Microsoft가 .NET 이니셔티브의 일부로 2000 년경에 개발했습니다." | "씨#" | ".그물" | "Microsoft의 일부로 2000 년경에 개발되었습니다." |
"C #은 Microsoft가 .NET 이니셔티브의 일부로 2000 년경에 개발했습니다." | ".그물" | ""(빈 문자열) | "발의" |
"C #은 Microsoft가 .NET 이니셔티브의 일부로 2000 년경에 개발했습니다." | ""(빈 문자열) | "씨#" | ""(빈 문자열) |
"C #은 Microsoft가 .NET 이니셔티브의 일부로 2000 년경에 개발했습니다." | ".그물" | "씨#" | ""(빈 문자열) |
"C #은 Microsoft가 .NET 이니셔티브의 일부로 2000 년경에 개발했습니다." | "알파벳" | "씨#" | ""(빈 문자열) |
"C #은 Microsoft가 .NET 이니셔티브의 일부로 2000 년경에 개발했습니다." | ".그물" | "XYZ" | ""(빈 문자열) |
"C #은 Microsoft가 .NET 이니셔티브의 일부로 2000 년경에 개발했습니다." | "알파벳" | "XYZ" | ""(빈 문자열) |
규칙
이것은 code-golf 입니다. 가장 적은 바이트의 대답이 이깁니다.
답변
APL (Dyalog 확장) , 24 바이트 ( SBCS )
의 배열을 묻는 전체 프로그램입니다 [EndKeyword,StartKeyword,InputString]
. 0 기반 인덱싱이 필요합니다.
⌂deb⊃(⌽⊢↓⍨1⍳⍨⊣,⍷)/⌽¨@0⊢⎕
온라인으로 시도하십시오!
⎕
입력 요청
⊢
그것에…
⌽¨@0
오프셋 0에서 발생하는 모든 요소 반전
(
… )/
다음 암묵적 기능을 사용하여 오른쪽에서 줄이십시오.
⍷
왼쪽 인수가 오른쪽 인수에서 시작하는 모든 위치를 부울 목록으로 표시
⊣,
그 앞에 왼쪽 인수를 추가
1⍳⍨
처음 1의 오프셋을 찾으십시오.
⊢↓⍨
오른쪽 인수에서 많은 선행 요소를 삭제
⌽
역순 (다음 번에 끝부터이 작업을 수행 한 후 순서를 되돌립니다.)
⊃
1 차원 어레이에서 0 차원 어레이로의 축소로 인한 인클로저 공개
⌂deb
d elete e nding (선행 및 후행) b lanks
JavaScript (ES6), 80 75 바이트
아래에 이스케이프 처리 된 인쇄 할 수없는 문자가 포함되어 있습니다.
(s,a,b)=>s.replace(b||/$/,"").replace(a,"").match(/ *(.*?) *|$/)[1]||""
온라인으로 시도하십시오!
댓글 작성
(s, a, b) => // s = input string, a = start keyword, b = end keyword
s.replace( // replace in s:
b || /$/, // look for the end keyword, or the regex /$/ if it's empty
"\3" // and replace it with ETX (end of text)
) //
.replace( // replace in the resulting string:
a, // look for the start keyword
"\2" // and replace it with STX (start of text)
) //
.match( // attempt to match:
/\2 *(.*?) *\3|$/ // "\2" STX ) // " *" followed by optional whitespace // "(.*?)" followed by a non-greedy string (the payload) // " *" followed by optional whitespace // "\3" followed by ETX // "|$" OR match an empty string to make sure that
// match() doesn't return null
[1] || "" // return the payload string, or an empty string if undefined
Python 3 , 86 77 75 바이트
movatica 덕분에 9 바이트 절약 !!! ovs
덕분에 2 바이트 절약 !!!
lambda s,a,b:s[s.find(a):(b in s)*s.find(b)if b else None][len(a):].strip()
온라인으로 시도하십시오!
JavaScript (Node.js) , 74 바이트
(s,a,b)=>s.substr(p=(s+a).indexOf(a)+a.length,b?s.indexOf(b)-p:1/0).trim()
온라인으로 시도하십시오!
아주 간단합니다 ...
Ruby , 66 바이트
->w,s,e,r=Regexp{"#{w[/#{r.quote s}\K.+(?=#{r.quote e})/]}".strip}
온라인으로 시도하십시오!
정규식을 사용하지 않는 또 다른 방법은
Ruby , 72 바이트
->w,s,e{"#{w[((w+s).index(s)+s.size rescue 0)...w.rindex(e)||0]}".strip}
온라인으로 시도하십시오!
Python 3 , 100 85 바이트
정규식 버전은 여전히 슬라이싱 알고리즘을 이길 수 없습니다 .
from re import*
r=escape
f=lambda s,b,e:(search(r(b)+'(.+)'+r(e),s)or' ')[1].strip()
온라인으로 시도하십시오!
Retina 0.8.2 , 60 바이트
(.*)¶(.+)?¶.*?\1 *(.*?) *(?<!(?=\2).*)(?(2)\2.*|$)|(.|¶)+ $3
온라인으로 시도하십시오! 별도의 줄에 시작, 끝, 문자열로 입력을 받지만 링크는 편의를 위해 쉼표로 구분 된 문자열, 끝, 시작에서 변환하는 헤더가있는 테스트 스위트입니다. 설명:
(.*)¶
시작 키워드와 일치합니다.
(.+)?¶
선택적으로 비어 있지 않은 끝 키워드와 일치합니다.
.*?\1
문자열에서 가능한 한 빨리 시작 키워드와 선택적 공백을 찾으십시오.
*(.*?) *
가능한 한 짧은 결과를 일치시키고 (문자열에서 가능한 한 빨리 end 키워드를 찾을 수 있도록) 그 주변의 공백도 잘라냅니다.
(?<!(?=\2).*)
이 시점에서 end 키워드가 아직 전달되지 않았는지 확인하십시오.
(?(2)\2.*|$)
종료 키워드가 비어 있으면 문자열의 끝에서만 일치하고 그렇지 않으면 종료 키워드와 나머지 문자열과 일치합니다.
|(.|¶)+
일치하는 항목이 없으면 모두 삭제하십시오.
$3
원하는 결과를 유지하십시오.
Wolfram 언어 (Mathematica) , 93 바이트
sStringTrim@StringTake[s,i=1;If[i*=-1;#=="",0,StringPosition[s,#][[1,i]]]-i&/@#]/._@_:>""&
온라인으로 시도하십시오!
빨간색 , 90 바이트
func[t s e][p:""if""<> s[append s" "]if e =""[e:[end]]parse t[thru s copy p to[opt" "e]]p]
온라인으로 시도하십시오!
C (GCC) , 168 (152) 143 132 112 바이트
@ceilingcat 덕분에 엄청난 -38
#define r strstr(c
*f(c,s,e)int*c,*s,*e;{return*e&&r,s)>r,e)|!r,s)|!r,e)||*e&&(*r,e)=0)?"":r,s)+strlen(s)+!!*s;}
온라인으로 시도하십시오!
JavaScript (ES6) 95 92 바이트, 정규식 없음!
(i,s,e,t=i.indexOf(s),r=i.lastIndexOf(e))=>t!=-1&r!=-1?(i.substring(t+s.length,r)).trim():''
그것을 시도하는 방법 :
브라우저의 JavaScript 콘솔을 열고 다음을 붙여 넣으십시오.
((i,s,e,t=i.indexOf(s),r=i.lastIndexOf(e))=>t!=-1&r!=-1?(i.substring(t+s.length,r)).trim():'')('C# was developed around 2000 by Microsoft as part of its .NET initiative', 'C#', '.NET')
목탄 , 41 바이트
≔⎇ζ…θ⌕θζθθ≔⎇η⪫Φ⪪θηκηθθ≔⌕AEθ›ι ¹ε¿ε✂θ⌊ε⊕⌈ε
온라인으로 시도하십시오! 링크는 자세한 코드 버전입니다. 키워드 중 하나가 비어 있더라도 입력에 충분한 줄 바꿈을 포함하도록주의하십시오. 설명:
≔⎇ζ…θ⌕θζθθ
end 키워드가 비어 있지 않으면 처음 나타나는 문자열을 자릅니다. (다행히도 CycleChop
입력이 음수이면 문자열을 비워 둡니다.)
≔⎇η⪫Φ⪪θηκηθθ
시작 키워드가 비어 있지 않으면 키워드에서 문자열을 분할하고 첫 번째 요소를 버리고 문자열을 다시 결합하십시오. 시작 키워드가 문자열에 나타나지 않으면 빈 문자열이됩니다.
≔⌕AEθ›ι ¹ε
문자열에 공백이 없는지 확인하십시오.
¿ε✂θ⌊ε⊕⌈ε
그렇다면 공백이 아닌 첫 번째부터 마지막까지 인쇄하십시오.
R , 111 바이트
function(s,a,b,c=?s,`?`=nchar,r=regexpr)trimws(substr(s,`if`((d=r(a,s,f=T))>0,d+?a,c),`if`(?b,r(b,s,f=T)-1,c)))
온라인으로 시도하십시오!
간단한 방법 : 사용하여 단어를 경계 발견은 regexpr
(인수 f
ixed =이 T
텍스트 문자열은 정규식으로 해석되지 않도록 후회)에 도착 substr
그들 사이 ING를, 다음 trim
의 S w
하이트 s
양쪽 끝에서 속도.
nchar
및 함수 regexpr
는 각각 두 번 사용 되기 때문에 단일 문자 별칭을 정의하는 것이 더 짧습니다. 의 경우 nchar
단항 연산자 ?
를 별칭으로 다시 정의 할 수도 있으므로 괄호가 필요하지 않습니다. 불행히도이 트릭은 regexpr
추가 인수 f
ixed = T
rue 를 제공해야하기 때문에 여기서는 불가능합니다 .
C # 114 바이트
(i,s,e)=>{int p=(i+(s??="")).IndexOf(s)+s.Length,q=$"{e}"==""?i.Length:i.IndexOf(e);return p<q?i[p..q].Trim():"";}