ตัวแยกสตริงย่อยที่มีคำสำคัญเฉพาะ

Jan 07 2021

ท้าทาย

เป้าหมายของความท้าทายนี้คือการสร้างฟังก์ชันที่รับสตริงอินพุตคีย์เวิร์ดเริ่มต้นและคีย์เวิร์ดปิดท้าย ผลลัพธ์ที่แยกออกมาจาก (แต่ไม่รวม) คีย์เวิร์ดเริ่มต้นที่กำหนดไปยังคีย์เวิร์ดปิดท้าย (แต่ยกเว้น) สตริงย่อยเอาต์พุตเป็นไปตามกฎด้านล่าง

  • ในทุกกรณีควรลบช่องว่างนำหน้า / ต่อท้ายในสตริงย่อยเอาต์พุต

  • หากคีย์เวิร์ดเริ่มต้นที่กำหนดเป็นสตริงว่างหมายความว่าจุดยึดอยู่ที่จุดเริ่มต้นของสตริงอินพุต มิฉะนั้นการเกิดขึ้นครั้งแรกของคำหลักเริ่มต้นที่ระบุคือจุดยึดเริ่มต้น หากไม่มีคำสำคัญเริ่มต้นใด ๆ เกิดขึ้นเอาต์พุตจะเป็นสตริงว่างเปล่า

  • หากคีย์เวิร์ดสิ้นสุดที่กำหนดเป็นสตริงว่างหมายความว่าจุดยึดอยู่ที่ส่วนท้ายของสตริงอินพุต มิฉะนั้นการเกิดขึ้นครั้งแรกของคำหลักปลายทางที่ระบุคือจุดยึดท้าย หากไม่มีการเกิดขึ้นของคีย์เวิร์ดปลายทางที่ระบุเอาต์พุตจะเป็นสตริงว่าง

  • หากตำแหน่งของจุดยึดเริ่มต้นอยู่หลังกว่าตำแหน่งของจุดยึดท้ายหรือส่วนหนึ่งของการเกิดขึ้นครั้งแรกของคีย์เวิร์ดเริ่มต้นที่กำหนดและส่วนหนึ่งของการเกิดขึ้นครั้งแรกของคีย์เวิร์ดสิ้นสุดที่กำหนดจะซ้อนทับกันเอาต์พุตจะเป็นสตริงว่าง

คล้ายกัน แต่แตกต่างจากดึงสตริงออกจากสตริงที่กำหนดจุดยึดเริ่มต้นและจุดสิ้นสุดที่กำหนดเป็นอักขระหลายตัว

นี่คือการใช้งานอ้างอิงที่ไม่มีการแก้ไขใน C #

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 # ได้รับการพัฒนาเมื่อประมาณปี 2000 โดย Microsoft โดยเป็นส่วนหนึ่งของการริเริ่ม. NET" "" (สตริงว่าง) "" (สตริงว่าง) "C # ได้รับการพัฒนาเมื่อประมาณปี 2000 โดย Microsoft โดยเป็นส่วนหนึ่งของการริเริ่ม. NET"
"C # ได้รับการพัฒนาเมื่อประมาณปี 2000 โดย Microsoft โดยเป็นส่วนหนึ่งของการริเริ่ม. NET" "" (สตริงว่าง) ".สุทธิ" "C # ได้รับการพัฒนาเมื่อประมาณปี 2000 โดย Microsoft เป็นส่วนหนึ่งของมัน"
"C # ได้รับการพัฒนาเมื่อประมาณปี 2000 โดย Microsoft โดยเป็นส่วนหนึ่งของการริเริ่ม. NET" "ค#" "" (สตริงว่าง) "ได้รับการพัฒนาเมื่อประมาณปี 2000 โดย Microsoft โดยเป็นส่วนหนึ่งของการริเริ่ม. NET"
"C # ได้รับการพัฒนาเมื่อประมาณปี 2000 โดย Microsoft โดยเป็นส่วนหนึ่งของการริเริ่ม. NET" "ค#" ".สุทธิ" "ได้รับการพัฒนาเมื่อประมาณปี 2000 โดย Microsoft ซึ่งเป็นส่วนหนึ่งของ"
"C # ได้รับการพัฒนาเมื่อประมาณปี 2000 โดย Microsoft โดยเป็นส่วนหนึ่งของการริเริ่ม. NET" ".สุทธิ" "" (สตริงว่าง) “ ความคิดริเริ่ม”
"C # ได้รับการพัฒนาเมื่อประมาณปี 2000 โดย Microsoft โดยเป็นส่วนหนึ่งของการริเริ่ม. NET" "" (สตริงว่าง) "ค#" "" (สตริงว่าง)
"C # ได้รับการพัฒนาเมื่อประมาณปี 2000 โดย Microsoft โดยเป็นส่วนหนึ่งของการริเริ่ม. NET" ".สุทธิ" "ค#" "" (สตริงว่าง)
"C # ได้รับการพัฒนาเมื่อประมาณปี 2000 โดย Microsoft โดยเป็นส่วนหนึ่งของการริเริ่ม. NET" "เอบีซี" "ค#" "" (สตริงว่าง)
"C # ได้รับการพัฒนาเมื่อประมาณปี 2000 โดย Microsoft โดยเป็นส่วนหนึ่งของการริเริ่ม. NET" ".สุทธิ" "XYZ" "" (สตริงว่าง)
"C # ได้รับการพัฒนาเมื่อประมาณปี 2000 โดย Microsoft โดยเป็นส่วนหนึ่งของการริเริ่ม. NET" "เอบีซี" "XYZ" "" (สตริงว่าง)

กฎ

นี่คือรหัสกอล์ฟ คำตอบที่มีจำนวนไบต์น้อยที่สุดจะชนะ

คำตอบ

2 Adám Jan 07 2021 at 15:32

APL (Dyalog Extended) , 24 ไบต์ ( SBCS )

โปรแกรมเต็มรูปแบบที่พร้อมท์สำหรับอาร์เรย์ของ[EndKeyword,StartKeyword,InputString]. ต้องการการสร้างดัชนีที่อิง 0

⌂deb⊃(⌽⊢↓⍨1⍳⍨⊣,⍷)/⌽¨@0⊢⎕

ลองออนไลน์!

 แจ้งให้ป้อนข้อมูล

 เมื่อนั้น…

⌽¨@0 ย้อนกลับองค์ประกอบทั้งหมดที่เกิดขึ้นที่ออฟเซ็ต 0

()/ ลดจากด้านขวาโดยใช้ฟังก์ชัน tacit ต่อไปนี้:

 ระบุด้วยรายการบูลีนตำแหน่งทั้งหมดที่อาร์กิวเมนต์ด้านซ้ายเริ่มต้นในอาร์กิวเมนต์ด้านขวา

⊣, นำหน้าอาร์กิวเมนต์ด้านซ้ายไปที่

1⍳⍨ หาค่าชดเชยของ 1 แรก

⊢↓⍨ ปล่อยองค์ประกอบชั้นนำจำนวนมากจากอาร์กิวเมนต์ที่ถูกต้อง

ย้อนกลับ (ในครั้งต่อไปให้ทำสิ่งนี้จากจุดสิ้นสุดและหลังจากนั้นย้อนกลับคำสั่งซื้อ)

 เปิดเผยกล่องหุ้มที่เกิดจากการลดจากอาร์เรย์ 1 มิติเป็นอาร์เรย์ 0 มิติ

⌂debdหนึ่งคำอี nding (ชั้นนำและต่อท้าย) lanks

5 Arnauld Jan 07 2021 at 11:31

JavaScript (ES6),  80  75 ไบต์

ซึ่งประกอบด้วยอักขระที่ไม่สามารถพิมพ์ได้ซึ่งมีการใช้ Escape ด้านล่าง

(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
3 Noodle9 Jan 08 2021 at 19:19

Python 3 , 86 77 75 ไบต์

บันทึก 9 ไบต์ขอบคุณmovatica !!!
บันทึก 2 ไบต์ขอบคุณOVs !!!

lambda s,a,b:s[s.find(a):(b in s)*s.find(b)if b else None][len(a):].strip()

ลองออนไลน์!

1 tsh Jan 07 2021 at 13:12

JavaScript (Node.js) , 74 ไบต์

(s,a,b)=>s.substr(p=(s+a).indexOf(a)+a.length,b?s.indexOf(b)-p:1/0).trim()

ลองออนไลน์!

ตรงไปตรงมาทีเดียว ...

1 vrintle Jan 07 2021 at 11:57

ทับทิม 66 ไบต์

->w,s,e,r=Regexp{"#{w[/#{r.quote s}\K.+(?=#{r.quote e})/]}".strip}

ลองออนไลน์!

อีกวิธีหนึ่งโดยไม่ต้องใช้นิพจน์ทั่วไป

ทับทิม 72 ไบต์

->w,s,e{"#{w[((w+s).index(s)+s.size rescue 0)...w.rindex(e)||0]}".strip}

ลองออนไลน์!

1 movatica Jan 08 2021 at 19:47

Python 3 , 100 85 ไบต์

เวอร์ชัน Regex ยังไม่สามารถเอาชนะอัลกอริทึมการแบ่งส่วนได้

from re import*
r=escape
f=lambda s,b,e:(search(r(b)+'(.+)'+r(e),s)or'  ')[1].strip()

ลองออนไลน์!

1 Neil Jan 09 2021 at 19:04

Retina 0.8.2 , 60 ไบต์

(.*)¶(.+)?¶.*?\1 *(.*?) *(?<!(?=\2).*)(?(2)\2.*|$)|(.|¶)+ $3

ลองออนไลน์! รับอินพุตเป็นจุดเริ่มต้นสิ้นสุดสตริงในบรรทัดที่แยกจากกัน แต่ลิงก์คือการทดสอบชุดที่มีส่วนหัวที่แปลงจากสตริงที่คั่นด้วยเครื่องหมายจุลภาคสิ้นสุดเริ่มต้นเพื่อความสะดวก คำอธิบาย:

(.*)¶

จับคู่คำหลักเริ่มต้น

(.+)?¶

เลือกที่จะจับคู่คำหลักที่ไม่ว่างเปล่า

.*?\1

ค้นหาคีย์เวิร์ดเริ่มต้นโดยเร็วที่สุดในสตริงและเว้นวรรคหรือไม่ก็ได้

 *(.*?) *

จับคู่ผลลัพธ์ให้สั้นที่สุดเท่าที่จะเป็นไปได้ (เพื่อให้พบคีย์เวิร์ดสุดท้ายเร็วที่สุดในสตริง) แต่ยังตัดช่องว่างรอบ ๆ

(?<!(?=\2).*)

ตรวจสอบให้แน่ใจว่ายังไม่ได้ส่งคีย์เวิร์ดปิดท้าย ณ จุดนี้

(?(2)\2.*|$)

หากคำหลักสิ้นสุดว่างเปล่าให้จับคู่เฉพาะที่ส่วนท้ายของสตริงมิฉะนั้นจะจับคู่คำหลักสุดท้ายและส่วนที่เหลือของสตริง

|(.|¶)+

หากไม่สามารถจับคู่สิ่งใดได้ให้ลบทุกอย่าง

$3

เก็บผลลัพธ์ที่ต้องการ

1 att Jan 07 2021 at 13:42

ภาษา Wolfram (Mathematica) 93 ไบต์

sStringTrim@StringTake[s,i=1;If[i*=-1;#=="",0,StringPosition[s,#][[1,i]]]-i&/@#]/._@_:>""&

ลองออนไลน์!

1 GalenIvanov Jan 07 2021 at 15:30

สีแดง 90 ไบต์

func[t s e][p:""if""<> s[append s" "]if e =""[e:[end]]parse t[thru s copy p to[opt" "e]]p]

ลองออนไลน์!

1 Davide Jan 10 2021 at 22:26

C (gcc) , 168 152 143 132 112 ไบต์

ขอบคุณมาก-38ที่ @ceilingcat

#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;}

ลองออนไลน์!

myjobistobehappy Jan 07 2021 at 13:05

JavaScript (ES6) 95 92 ไบต์ไม่มี Regex!

(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')
Neil Jan 09 2021 at 22:40

ถ่าน 41 ไบต์

≔⎇ζ…θ⌕θζθθ≔⎇η⪫Φ⪪θηκηθθ≔⌕AEθ›ι ¹ε¿ε✂θ⌊ε⊕⌈ε

ลองออนไลน์! ลิงก์คือรหัสเวอร์ชันที่ละเอียด โปรดรวมบรรทัดใหม่ให้เพียงพอในอินพุตแม้ว่าคำหลักคำใดคำหนึ่งจะว่างเปล่าก็ตาม คำอธิบาย:

≔⎇ζ…θ⌕θζθθ

หากคีย์เวิร์ดสิ้นสุดไม่ว่างเปล่าให้ตัดสตริงที่ปรากฏครั้งแรก (โชคดีที่จะCycleChopตัดสตริงให้ว่างเปล่าหากอินพุตเป็นลบ)

≔⎇η⪫Φ⪪θηκηθθ

หากคีย์เวิร์ดเริ่มต้นไม่ว่างเปล่าให้แยกสตริงของคีย์เวิร์ดทิ้งองค์ประกอบแรกและรวมสตริงอีกครั้ง ผลลัพธ์นี้เป็นสตริงว่างหากคีย์เวิร์ดเริ่มต้นไม่ปรากฏในสตริง

≔⌕AEθ›ι ¹ε

ตรวจสอบว่าสตริงมีช่องว่างหรือไม่

¿ε✂θ⌊ε⊕⌈ε

ถ้าเป็นเช่นนั้นให้พิมพ์จากช่องว่างแรกถึงช่องสุดท้าย

DominicvanEssen Jan 11 2021 at 06:31

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)))

ลองออนไลน์!

วิธีการตรงไปตรงมา: พบ bounding คำโดยใช้regexpr(ที่มีข้อโต้แย้งfคงที่ = Tเสียใจเพื่อให้มั่นใจว่าสตริงข้อความที่ไม่ได้ตีความว่าเป็น regex ก) ได้รับsubstrไอเอ็นจีระหว่างพวกเขาและจากนั้นtrims wHite sก้าวจากปลายทั้งสอง

เนื่องจากฟังก์ชันncharและregexprแต่ละรายการถูกใช้สองครั้งจึงสั้นกว่าในการกำหนดนามแฝงอักขระเดี่ยว ในกรณีนี้ncharเราสามารถกำหนดโอเปอเรเตอร์ยูนารีใหม่?เป็นนามแฝงเพื่อหลีกเลี่ยงความจำเป็นในการใช้วงเล็บ น่าเสียดายที่เคล็ดลับนี้ไม่สามารถทำได้ที่นี่regexprเนื่องจากจำเป็นต้องป้อนอาร์กิวเมนต์เพิ่มเติมfixed = True

pinkfloydx33 Jan 24 2021 at 20:05

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():"";}