Ekstraktor Sub-string dengan Kata Kunci Tertentu

Jan 07 2021

Tantangan

Tujuan dari tantangan ini adalah untuk membuat fungsi yang mengambil string masukan, kata kunci awal, dan kata kunci akhir. Keluaran hasil ekstraksi adalah dari (tetapi dikecualikan) kata kunci awal yang diberikan menjadi (tetapi dikecualikan) kata kunci akhir. Output sub-string mengikuti aturan seperti di bawah ini.

  • Dalam semua kasus, spasi di depan / di belakang dalam sub-string keluaran harus dihilangkan.

  • Jika kata kunci awal yang diberikan adalah string kosong, itu berarti jangkar berada di awal string input. Jika tidak, kemunculan pertama dari kata kunci awal yang diberikan adalah jangkar awal. Jika tidak ada kemunculan kata kunci awal yang diberikan, hasilnya adalah string kosong.

  • Jika kata kunci akhir yang diberikan adalah string kosong, itu berarti jangkar berada di akhir string input. Jika tidak, kemunculan pertama dari kata kunci akhir yang diberikan adalah jangkar akhir. Jika tidak ada kemunculan kata kunci akhir yang diberikan, hasilnya adalah string kosong.

  • Jika lokasi jangkar awal adalah setelah dari lokasi jangkar akhir, atau bagian dari kemunculan pertama dari kata kunci awal yang diberikan dan bagian dari kemunculan pertama dari kata kunci akhir yang diberikan tumpang tindih, hasilnya adalah string kosong.

Mirip tetapi berbeda dari Ekstrak string dari string tertentu , jangkar awal dan akhir yang diberikan terdiri dari beberapa karakter.

Berikut adalah implementasi referensi yang tidak terputus di 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();
}

Contoh Input dan Output

Contoh input dan output terdaftar seperti di bawah ini.

String Input Mulai Kata Kunci Kata Kunci Akhir Keluaran
"C # dikembangkan sekitar tahun 2000 oleh Microsoft sebagai bagian dari inisiatif .NET-nya" "" (string kosong) "" (string kosong) "C # dikembangkan sekitar tahun 2000 oleh Microsoft sebagai bagian dari inisiatif .NET-nya"
"C # dikembangkan sekitar tahun 2000 oleh Microsoft sebagai bagian dari inisiatif .NET-nya" "" (string kosong) ".BERSIH" "C # dikembangkan sekitar tahun 2000 oleh Microsoft sebagai bagian dari"
"C # dikembangkan sekitar tahun 2000 oleh Microsoft sebagai bagian dari inisiatif .NET-nya" "C #" "" (string kosong) "dikembangkan sekitar tahun 2000 oleh Microsoft sebagai bagian dari inisiatif .NET-nya"
"C # dikembangkan sekitar tahun 2000 oleh Microsoft sebagai bagian dari inisiatif .NET-nya" "C #" ".BERSIH" "dikembangkan sekitar tahun 2000 oleh Microsoft sebagai bagian dari"
"C # dikembangkan sekitar tahun 2000 oleh Microsoft sebagai bagian dari inisiatif .NET-nya" ".BERSIH" "" (string kosong) "prakarsa"
"C # dikembangkan sekitar tahun 2000 oleh Microsoft sebagai bagian dari inisiatif .NET-nya" "" (string kosong) "C #" "" (string kosong)
"C # dikembangkan sekitar tahun 2000 oleh Microsoft sebagai bagian dari inisiatif .NET-nya" ".BERSIH" "C #" "" (string kosong)
"C # dikembangkan sekitar tahun 2000 oleh Microsoft sebagai bagian dari inisiatif .NET-nya" "ABC" "C #" "" (string kosong)
"C # dikembangkan sekitar tahun 2000 oleh Microsoft sebagai bagian dari inisiatif .NET-nya" ".BERSIH" "XYZ" "" (string kosong)
"C # dikembangkan sekitar tahun 2000 oleh Microsoft sebagai bagian dari inisiatif .NET-nya" "ABC" "XYZ" "" (string kosong)

Aturan

Ini adalah kode-golf . Jawaban dengan byte paling sedikit menang.

Jawaban

2 Adám Jan 07 2021 at 15:32

APL (Dyalog Extended) , 24 byte ( SBCS )

Program lengkap yang meminta array [EndKeyword,StartKeyword,InputString]. Memerlukan pengindeksan berbasis 0.

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

Cobalah secara online!

 meminta masukan

 itu ...

⌽¨@0 membalikkan semua elemen yang terjadi pada offset 0

()/ Kurangi dari kanan menggunakan fungsi diam-diam berikut:

 tunjukkan dengan daftar Boolean semua tempat di mana argumen kiri dimulai di argumen kanan

⊣, tambahkan argumen kiri untuk itu

1⍳⍨ temukan offset dari 1 yang pertama

⊢↓⍨ hilangkan banyak elemen utama dari argumen yang benar

mundur (lain kali, lakukan ini dari akhir, dan setelah itu, kembalikan urutan)

 mengungkapkan selungkup yang disebabkan oleh reduksi dari larik 1 dimensi menjadi larik 0 dimensi

⌂debd elete e nding (leading and trailing) b lanks

5 Arnauld Jan 07 2021 at 11:31

JavaScript (ES6),  80  75 byte

Ini berisi beberapa karakter yang tidak dapat dicetak yang lolos di bawah ini.

(s,a,b)=>s.replace(b||/$/,"").replace(a,"").match(/ *(.*?) *|$/)[1]||""

Cobalah secara online!

Berkomentar

(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 byte

Disimpan 9 byte berkat movatica !!!
Disimpan 2 byte berkat ovs !!!

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

Cobalah secara online!

1 tsh Jan 07 2021 at 13:12

JavaScript (Node.js) , 74 byte

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

Cobalah secara online!

Cukup mudah ...

1 vrintle Jan 07 2021 at 11:57

Ruby , 66 byte

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

Cobalah secara online!

Metode lain tanpa menggunakan regex,

Ruby , 72 byte

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

Cobalah secara online!

1 movatica Jan 08 2021 at 19:47

Python 3 , 100 85 byte

Versi Regex, masih tidak bisa mengalahkan algoritma pemotongan .

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

Cobalah secara online!

1 Neil Jan 09 2021 at 19:04

Retina 0.8.2 , 60 byte

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

Cobalah secara online! Mengambil input sebagai start, end, string pada baris terpisah tetapi link adalah untuk menguji suite dengan header yang mengkonversi dari string yang dipisahkan koma, end, start untuk kenyamanan. Penjelasan:

(.*)¶

Cocokkan kata kunci awal.

(.+)?¶

Secara opsional, cocokkan kata kunci akhir yang tidak kosong.

.*?\1

Temukan kata kunci awal sedini mungkin dalam string, ditambah spasi opsional.

 *(.*?) *

Cocokkan hasil sesingkat mungkin (sehingga kata kunci akhir ditemukan sedini mungkin dalam string) tetapi juga potong spasi di sekitarnya.

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

Pastikan kata kunci akhir belum dikirimkan pada saat ini.

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

Jika kata kunci akhir kosong maka hanya cocok di akhir string jika tidak cocok dengan kata kunci akhir dan sisa string.

|(.|¶)+

Jika tidak mungkin mencocokkan apa pun, hapus semuanya.

$3

Pertahankan hasil yang diinginkan.

1 att Jan 07 2021 at 13:42

Bahasa Wolfram (Mathematica) , 93 byte

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

Cobalah secara online!

1 GalenIvanov Jan 07 2021 at 15:30

Merah , 90 byte

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

Cobalah secara online!

1 Davide Jan 10 2021 at 22:26

C (gcc) , 168 152 143 132 112 bytes

Besar -38 berkat @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;}

Cobalah secara online!

myjobistobehappy Jan 07 2021 at 13:05

JavaScript (ES6) 95 92 Bytes, Tanpa Regex!

(i,s,e,t=i.indexOf(s),r=i.lastIndexOf(e))=>t!=-1&r!=-1?(i.substring(t+s.length,r)).trim():''

Cara mencobanya:

Buka Konsol JavaScript browser Anda dan tempel perintah berikut.

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

Arang , 41 byte

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

Cobalah secara online! Tautan adalah untuk verbose versi kode. Berhati-hatilah untuk menyertakan cukup baris baru dalam masukan meskipun salah satu kata kuncinya kosong. Penjelasan:

≔⎇ζ…θ⌕θζθθ

Jika kata kunci akhir tidak kosong, potong string pada tampilan pertamanya. (Untungnya CycleChopmemotong string menjadi kosong jika inputnya negatif.)

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

Jika kata kunci start tidak kosong maka pisahkan string pada kata kunci tersebut, buang elemen pertama, dan gabungkan kembali string tersebut. Ini menghasilkan string kosong jika kata kunci start tidak muncul dalam string.

≔⌕AEθ›ι ¹ε

Periksa apakah string memiliki non-spasi.

¿ε✂θ⌊ε⊕⌈ε

Jika demikian, maka cetak dari non-spasi pertama hingga terakhir.

DominicvanEssen Jan 11 2021 at 06:31

R , 111 byte

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

Cobalah secara online!

Pendekatan langsung: menemukan kata-kata pembatas menggunakan regexpr(dengan argumen fixed = True untuk memastikan bahwa string teks tidak diinterpretasikan sebagai regex), mendapatkan substring di antara mereka, dan kemudian trims the white space dari kedua ujungnya.

Karena fungsi nchardan regexprmasing-masing digunakan dua kali, itu lebih pendek untuk mendefinisikan alias satu karakter. Dalam kasus nchar, kita bahkan dapat mendefinisikan ulang operator unary ?sebagai aliasnya, sehingga kita tidak perlu menggunakan tanda kurung. Sayangnya, trik ini tidak mungkin dilakukan di sini regexprkarena perlu memberinya argumen tambahan fixed = True.

pinkfloydx33 Jan 24 2021 at 20:05

C # 114 byte

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