एक स्ट्रिंग को एक सीमांकक के आधार पर स्ट्रिंग की एक सरणी में विभाजित करें


84

मैं एक डेल्फी फ़ंक्शन खोजने की कोशिश कर रहा हूं जो एक इनपुट स्ट्रिंग को एक सीमांकक के आधार पर स्ट्रिंग की एक सरणी में विभाजित करेगा। मैंने Google पर बहुत कुछ पाया है, लेकिन लगता है कि सभी के पास अपने मुद्दे हैं और मैं उनमें से किसी को भी काम करने में सक्षम नहीं कर पाया हूं।

मुझे बस एक स्ट्रिंग को विभाजित करने की आवश्यकता है जैसे: "word:doc,txt,docx"':' पर ​​आधारित एक सरणी में। परिणाम होगा ['word', 'doc,txt,docx']

क्या किसी के पास एक फ़ंक्शन है जो वे जानते हैं कि काम करता है?

धन्यवाद

जवाबों:


86

आप एक स्ट्रिंग को विभाजित करने के लिए TStrings.DelimitedText संपत्ति का उपयोग कर सकते हैं

इस नमूने की जाँच करें

program Project28;

{$APPTYPE CONSOLE}

uses
  Classes,
  SysUtils;

procedure Split(Delimiter: Char; Str: string; ListOfStrings: TStrings) ;
begin
   ListOfStrings.Clear;
   ListOfStrings.Delimiter       := Delimiter;
   ListOfStrings.StrictDelimiter := True; // Requires D2006 or newer.
   ListOfStrings.DelimitedText   := Str;
end;


var
   OutPutList: TStringList;
begin
   OutPutList := TStringList.Create;
   try
     Split(':', 'word:doc,txt,docx', OutPutList) ;
     Writeln(OutPutList.Text);
     Readln;
   finally
     OutPutList.Free;
   end;
end.

अपडेट करें

की व्याख्या के लिए इस लिंक को देखें StrictDelimiter


22
दुर्भाग्य से कई "पुराने" डेल्फी संस्करणों में एक बग है (यह सुनिश्चित नहीं है कि किस रिलीज के साथ यह तय हो गया है) जिसका प्रभाव है कि अंतरिक्ष चरित्र को हमेशा सीमांकक के रूप में उपयोग किया जाता है। तो इसको संभाल कर संभालो !!
सिंह

16
हाँ। आप StrictDelimiter को सही पर सेट करना चाहते हैं, और यदि StrictDelimiter संपत्ति आपके डेल्फी के संस्करण में उपलब्ध नहीं है, तो इस तकनीक का उपयोग न करें! लेकिन अगर यह है, तो यह बहुत उपयोगी है।
मेसन व्हीलर

3
यह बग नहीं था, यह डी 1 या डी 2 में एक (कष्टप्रद) डिजाइन निर्णय तरीका था। कॉमाटेक्स्ट को किसी भी क्षेत्र को उद्धरण के साथ रिक्त स्थान के साथ संलग्न करना था। यदि इनपुट में रिक्त स्थान वाले किसी भी फ़ील्ड के दोहरे उद्धरण हैं, तो परिणाम सही है।
गेरी कोल

1
मेरे पालतू जानवरों में से एक तब होता है जब लोग अनावश्यक रूप से चर / पैरामीटर नामों में संकेतक लगाते हैं। पास्कल दृढ़ता से टाइप किया जाता है - यह निरर्थक टाइपिंग (उंगली व्यायाम की विविधता का) और भ्रमित करने वाला है जब प्रकार सूचक गलत है, जैसा कि इस मामले में है: ArrayOfStrings एक सरणी नहीं है (और जैसे कि सवाल का जवाब नहीं दिया जाता है) ।
डेल्टिक्स

6
इस उत्तर को जारी रखने वाले सभी के लिए, कृपया ध्यान दें कि यह एक सरणी नहीं देता है, जैसा कि प्रश्न में निर्दिष्ट है। इस उद्योग में अपूर्ण आवश्यकताओं का विनिर्देश एक बड़ी समस्या है, बताई गई आवश्यकताओं की अनदेखी करना और किसी से कुछ न माँगना दूसरी बड़ी समस्या है। या तो अनुमोदन केवल बुरे अभ्यास को प्रोत्साहित करता है। ;)
डेल्टिक्स

67

एक Splitफंक्शन इंजीनियरिंग की कोई आवश्यकता नहीं है । यह पहले से मौजूद है, देखें Classes.ExtractStrings:।

इसे निम्नलिखित तरीके से उपयोग करें:

program Project1;

{$APPTYPE CONSOLE}

uses
  Classes;

var
  List: TStrings;
begin
  List := TStringList.Create;
  try
    ExtractStrings([':'], [], PChar('word:doc,txt,docx'), List);
    WriteLn(List.Text);
    ReadLn;
  finally
    List.Free;
  end;
end.

और सवाल का पूरी तरह से जवाब देने के लिए; Listतत्वों के साथ वांछित सरणी का प्रतिनिधित्व करता है:

List[0] = 'word'
List[1] = 'doc,txt,docx'

14
अर्कस्ट्रीम बहुत ही अनम्य है: "कैरिज रिटर्न, न्यूलाइन वर्ण और उद्धरण वर्ण (सिंगल या डबल) हमेशा विभाजक के रूप में होते हैं।" और "नोट: एक्सट्रैक्टस्ट्रीम सूची में खाली तारों को नहीं जोड़ता है।"
awmross

समस्या एक splitफ़ंक्शन को इंजीनियर करने के लिए नहीं है , बल्कि एक TStringsवस्तु की आवश्यकता है । और inflexibility (@awmross) उल्लेखों के कारण, मैं फ्रैंक का समाधान
वुल्फ

50

आप उपयोग कर सकते हैं StrUtils.SplitString

function SplitString(const S, Delimiters: string): TStringDynArray;

प्रलेखन से इसका विवरण :

अलग-अलग हिस्सों में एक स्ट्रिंग को विभाजित करता है जो निर्दिष्ट सीमांकक वर्णों द्वारा सीमांकित होता है।

स्प्लिटस्ट्रिंग अलग-अलग हिस्सों में एक स्ट्रिंग को विभाजित करता है जिसे निर्दिष्ट सीमांकक वर्णों द्वारा सीमांकित किया जाता है। एस विभाजित होने के लिए स्ट्रिंग है। डेलीमीटर एक स्ट्रिंग है जिसमें सीमांकक के रूप में परिभाषित वर्ण होते हैं।

स्प्लिटस्ट्रिंग प्रकार के स्ट्रिंग्स का एक प्रकार देता है System.Types.TStringDynArray जिसमें मूल स्ट्रिंग के विभाजन भागों होते हैं।


3
Hmmm, डेल्फी 2010 के मेरे संस्करण में नहीं है (XMLDoc में और (Indy इकाई) IdStrings में एक भाजित दिनचर्या है, लेकिन इनमें से कोई भी ऐसा नहीं है जो पोस्टर चाहता है और XMLDoc दिनचर्या इकाई इंटरफ़ेस के माध्यम से वैसे भी उजागर नहीं होता है)।
Deltics

3
फंक्शन स्प्लिस्ट्रिंग (कॉन्स्टेंस एस, डेलिमिटर: स्ट्रिंग): TStringDynArray; StrUtils.pas में परिभाषित
एलेक्स

मैं फ़ाइल StrUtils.pas (वर्तमान में भी) को शामिल करने में सक्षम नहीं हूं।
सत्यसेक

यह एक स्ट्रिंग को "सरणी" में विभाजित करने का एक उदाहरण है।
bvj

सबसे अच्छी बात यह है कि यह एक स्ट्रिंग सीमांकक को स्वीकार करता है जैसा कि अन्य उत्तरों में चार सीमांकक के विपरीत है।
user30478

42

डेल्फी XE3 में पेश SysUtils.TStringHelper.Split फ़ंक्शन का उपयोग करना :

var
  MyString: String;
  Splitted: TArray<String>;
begin
  MyString := 'word:doc,txt,docx';
  Splitted := MyString.Split([':']);
end.

यह स्ट्रिंग के एक सरणी में दिए गए सीमांकक के साथ एक स्ट्रिंग को विभाजित करेगा।


18

मैं हमेशा कुछ इसी तरह का उपयोग करें:

Uses
   StrUtils, Classes;

Var
  Str, Delimiter : String;
begin
  // Str is the input string, Delimiter is the delimiter
  With TStringList.Create Do
  try
    Text := ReplaceText(S,Delim,#13#10);

    // From here on and until "finally", your desired result strings are
    // in strings[0].. strings[Count-1)

  finally
    Free; //Clean everything up, and liberate your memory ;-)
  end;

end;

2
पुराने डेल्फी संस्करणों के उपयोगकर्ताओं के लिए महान समाधान।
वुल्फ

C ++ बिल्डर 6 उपयोगकर्ता: संबंधित फ़ंक्शन हैStrutils::AnsiReplaceText
वुल्फ

आश्चर्यजनक रूप से सरल। डेल्फी 7 में साथ काम करना list.Text := AnsiReplaceStr(source, delimiter, #13#10);:।
एलेनड

डेल्फी 6 में SysUtils.StringReplace
pyfyc

14

करने के लिए इसी तरह के विस्फोट () MEF द्वारा की पेशकश समारोह, लेकिन मतभेद (जिनमें से एक मैं बग समाधान पर विचार करें) के एक जोड़े के साथ:

  type
    TArrayOfString = array of String;


  function SplitString(const aSeparator, aString: String; aMax: Integer = 0): TArrayOfString;
  var
    i, strt, cnt: Integer;
    sepLen: Integer;

    procedure AddString(aEnd: Integer = -1);
    var
      endPos: Integer;
    begin
      if (aEnd = -1) then
        endPos := i
      else
        endPos := aEnd + 1;

      if (strt < endPos) then
        result[cnt] := Copy(aString, strt, endPos - strt)
      else
        result[cnt] := '';

      Inc(cnt);
    end;

  begin
    if (aString = '') or (aMax < 0) then
    begin
      SetLength(result, 0);
      EXIT;
    end;

    if (aSeparator = '') then
    begin
      SetLength(result, 1);
      result[0] := aString;
      EXIT;
    end;

    sepLen := Length(aSeparator);
    SetLength(result, (Length(aString) div sepLen) + 1);

    i     := 1;
    strt  := i;
    cnt   := 0;
    while (i <= (Length(aString)- sepLen + 1)) do
    begin
      if (aString[i] = aSeparator[1]) then
        if (Copy(aString, i, sepLen) = aSeparator) then
        begin
          AddString;

          if (cnt = aMax) then
          begin
            SetLength(result, cnt);
            EXIT;
          end;

          Inc(i, sepLen - 1);
          strt := i + 1;
        end;

      Inc(i);
    end;

    AddString(Length(aString));

    SetLength(result, cnt);
  end;

अंतर:

  1. aMax पैरामीटर वापस आने के लिए स्ट्रिंग्स की संख्या को सीमित करता है
  2. यदि इनपुट स्ट्रिंग को एक विभाजक द्वारा समाप्त किया जाता है तो एक नाममात्र "खाली" अंतिम स्ट्रिंग मौजूद माना जाता है

उदाहरण:

SplitString(':', 'abc') returns      :    result[0]  = abc

SplitString(':', 'a:b:c:') returns   :    result[0]  = a
                                          result[1]  = b
                                          result[2]  = c
                                          result[3]  = <empty string>

SplitString(':', 'a:b:c:', 2) returns:    result[0]  = a
                                          result[1]  = b

यह अनुगामी विभाजक और कुख्यात "खाली अंतिम तत्व" है जिसे मैं बग फिक्स मानता हूं।

मैंने अपने द्वारा सुझाए गए मेमोरी आवंटन परिवर्तन को भी शामिल किया, (मैंने गलती से सुझाव दिया कि इनपुट स्ट्रिंग में अधिकतम 50% विभाजक हो सकते हैं, लेकिन यह निश्चित रूप से 100% विभाजक तारों से मिलकर बन सकता है, खाली तत्वों की एक सरणी पैदा करता है!)


7

धमाका बहुत हाई स्पीड फंक्शन है, सोर्स एल्होरीटम टीस्ट्रेस घटक से मिलता है। मैं विस्फोट के लिए अगले परीक्षण का उपयोग करता हूं: 134217733 डेटा के बाइट्स की व्याख्या करें, मुझे 19173962 तत्व मिलते हैं, काम का समय: 2984 एमएस।

Implode बहुत कम गति का कार्य है, लेकिन मैं इसे आसान लिखता हूं।

{ ****************************************************************************** }
{  Explode/Implode (String <> String array)                                      }
{ ****************************************************************************** }
function Explode(S: String; Delimiter: Char): Strings; overload;
var I, C: Integer; P, P1: PChar;
begin
    SetLength(Result, 0);
    if Length(S) = 0 then Exit;
    P:=PChar(S+Delimiter); C:=0;
    while P^ <> #0 do begin
       P1:=P;
       while (P^ <> Delimiter) do P:=CharNext(P);
       Inc(C);
       while P^ in [#1..' '] do P:=CharNext(P);
       if P^ = Delimiter then begin
          repeat
           P:=CharNext(P);
          until not (P^ in [#1..' ']);
       end;
    end;
    SetLength(Result, C);
    P:=PChar(S+Delimiter); I:=-1;
    while P^ <> #0 do begin
       P1:=P;
       while (P^ <> Delimiter) do P:=CharNext(P);
       Inc(I); SetString(Result[I], P1, P-P1);
       while P^ in [#1..' '] do P:=CharNext(P);
       if P^ = Delimiter then begin
          repeat
           P:=CharNext(P);
          until not (P^ in [#1..' ']);
       end;
    end;
end;

function Explode(S: String; Delimiter: Char; Index: Integer): String; overload;
var I: Integer; P, P1: PChar;
begin
    if Length(S) = 0 then Exit;
    P:=PChar(S+Delimiter); I:=1;
    while P^ <> #0 do begin
       P1:=P;
       while (P^ <> Delimiter) do P:=CharNext(P);
        SetString(Result, P1, P-P1);
        if (I <> Index) then Inc(I) else begin
           SetString(Result, P1, P-P1); Exit;
        end;
       while P^ in [#1..' '] do P:=CharNext(P);
       if P^ = Delimiter then begin
          repeat
           P:=CharNext(P);
          until not (P^ in [#1..' ']);
       end;
    end;
end;

function Implode(S: Strings; Delimiter: Char): String;
var iCount: Integer;
begin
     Result:='';
     if (Length(S) = 0) then Exit;
     for iCount:=0 to Length(S)-1 do
     Result:=Result+S[iCount]+Delimiter;
     System.Delete(Result, Length(Result), 1);
end;

3
यह संकलन नहीं करता है: Stringsएक प्रकार नहीं है।
NGLN

7
var  
    su  : string;        // What we want split
    si  : TStringList;   // Result of splitting
    Delimiter : string;
    ...
    Delimiter := ';';
    si.Text := ReplaceStr(su, Delimiter, #13#10);

सी सूची में लाइनों में विभाजित तार शामिल होंगे।


6

आप अपना खुद का फंक्शन बना सकते हैं जो स्ट्रिंग का ट्रेयर लौटाता है:

function mySplit(input: string): TArray<string>;
var
  delimiterSet: array [0 .. 0] of char; 
     // split works with char array, not a single char
begin
  delimiterSet[0] := '&'; // some character
  result := input.Split(delimiterSet);
end;

5

यहां एक विस्फोट कार्य का कार्यान्वयन है जो मानक फ़ंक्शन के रूप में कई अन्य प्रोग्रामिंग भाषाओं में उपलब्ध है:

type 
  TStringDynArray = array of String;

function Explode(const Separator, S: string; Limit: Integer = 0): TStringDynArray; 
var 
  SepLen: Integer; 
  F, P: PChar; 
  ALen, Index: Integer; 
begin 
  SetLength(Result, 0); 
  if (S = '') or (Limit < 0) then Exit; 
  if Separator = '' then 
  begin 
    SetLength(Result, 1); 
    Result[0] := S; 
    Exit; 
  end; 
  SepLen := Length(Separator); 
  ALen := Limit; 
  SetLength(Result, ALen); 

  Index := 0; 
  P := PChar(S); 
  while P^ <> #0 do 
  begin 
    F := P; 
    P := AnsiStrPos(P, PChar(Separator)); 
    if (P = nil) or ((Limit > 0) and (Index = Limit - 1)) then P := StrEnd(F); 
    if Index >= ALen then 
    begin 
      Inc(ALen, 5); 
      SetLength(Result, ALen); 
    end; 
    SetString(Result[Index], F, P - F); 
    Inc(Index); 
    if P^ <> #0 then Inc(P, SepLen); 
  end; 
  if Index < ALen then SetLength(Result, Index); 
end; 

नमूना उपयोग:

var
  res: TStringDynArray;
begin
  res := Explode(':', yourString);

2
परिणाम की लंबाई के प्रबंधन / पूर्वानुमान के लिए इस कोड में कुछ अजीब और संभावित रूप से अक्षम विकल्प हैं। परिणाम सरणी को बढ़ाकर, स्मृति पुन: आवंटन और विखंडन की संभावना बढ़ जाती है। अधिक कुशल एक प्रारंभिक लंबाई निर्धारित करना होगा जितना कि यह संभवतः हो सकता है जितना बड़ा हो सकता है अर्थात यह मान लें कि इनपुट स्ट्रिंग में 50% विभाजक तार = लंबाई (S) div (2 * लंबाई (विभाजक) है) फिर इसे वास्तविक संख्या पर सेट करें। आइटम जब किया गया। 1 आवंटन के बाद संभावित रूप से एक एकल ट्रंकेशन।
डेल्टिक्स

इसके अलावा, आप सीमा पैरामीटर के उद्देश्य की व्याख्या नहीं करते हैं। मैंने सहजता से यह अपेक्षा की कि अधिकतम संख्या में ऐसे सबस्ट्रिंग को सेट किया जाए, जब वास्तव में यह इनपुट स्ट्रिंग में वर्णों के पहले "लिमिट" # के लिए सब्सट्रिंग का पता लगाने में बाधा उत्पन्न करता है। यह तब से व्यर्थ लगता है, जब आपको यह करने की आवश्यकता होती है कि आप आवश्यक प्रतिस्थापन के बस एक विस्फोट () से अधिक विस्फोट () का संचालन कर सकते हैं। अधिकतम संख्या में सबस्ट्रिंग सेट करने के लिए सीमा का उपयोग करना कहीं अधिक उपयोगी होगा।
डेल्टिक्स

@ डल्टिक्स: किसी ने भी दावा नहीं किया कि यह एक अत्यधिक अनुकूलित फ़ंक्शन है, और किसी ने भी एक के लिए नहीं पूछा, इसलिए मैं कुछ हद तक आपकी शिकायत को नहीं समझता हूं। लेकिन शायद आप उन लोगों में से एक हैं जो सब कुछ अनुकूलित करते हैं, भले ही यह आवश्यक हो या नहीं ...
सिंह

1
मैं उस तरह का आदमी हूं जो अनावश्यक रूप से अक्षम कोड नहीं लिखता है, फिर बाद में अनुकूलन के बारे में चिंता करें। यह कोड का सूक्ष्मता से विश्लेषण करने और कुछ miniscule अनुकूलन क्षमता प्राप्त करने का मामला नहीं था, यह केवल एक स्पष्ट और आसानी से अक्षमता थी: सन्निहित स्मृति की वृद्धिशील वृद्धि जो आसानी से पूर्व-आवंटित की जा सकती है और बाद में छंटनी की जा सकती है।
डेल्टिक्स

इसके अलावा @Mef: और यह एक शिकायत नहीं थी, यह एक टिप्पणी थी, एक अवलोकन था। लेकिन इससे भी महत्वपूर्ण बात यह है कि आपके कोड में यह भी शामिल था कि मैं किस बग पर विचार करूंगा (स्पष्टीकरण के लिए मेरा विकल्प देखें)।
डेल्टिक्स

5

मैंने यह फ़ंक्शन लिखा है जो विशिष्ट सीमांकक द्वारा अलग किए गए तारों की लिंक की गई सूची देता है। मॉड्यूल के बिना शुद्ध मुक्त पास्कल।

Program split_f;

type
    PTItem = ^TItem;
    TItem = record
        str : string;
        next : PTItem;
    end;

var
    s : string;
    strs : PTItem;

procedure split(str : string;delim : char;var list : PTItem);
var
    i : integer;
    buff : PTItem;
begin
    new(list);
    buff:= list;
    buff^.str:='';
    buff^.next:=nil;

    for i:=1 to length(str) do begin
        if (str[i] = delim) then begin
            new(buff^.next);
            buff:=buff^.next;
            buff^.str := '';
            buff^.next := nil;
        end
        else
        buff^.str:= buff^.str+str[i];
    end;
end;

procedure print(var list:PTItem);
var
    buff : PTItem;
begin
    buff := list;
    while buff<>nil do begin
        writeln(buff^.str);
        buff:= buff^.next;
    end;
end;

begin

    s := 'Hi;how;are;you?';

    split(s, ';', strs);
    print(strs);


end.

3

जेडी कोड लाइब्रेरी बिल्ट-इन स्प्लिट फ़ंक्शन के साथ एक बढ़ी हुई स्ट्रिंगलिस्ट प्रदान करता है, जो मौजूदा पाठ को जोड़ने और बदलने दोनों में सक्षम है। यह संदर्भ-गणना इंटरफ़ेस भी प्रदान करता है। तो इसका उपयोग पुराने डेल्फी संस्करणों के साथ भी किया जा सकता है, जिसमें कोई स्प्लिटस्ट्रीम नहीं है और बिना सावधानी के और स्टॉक TStringList के थोड़े थकाऊ कस्टमाइज़ेशन केवल निर्दिष्ट सीमांकक का उपयोग करने के लिए।

उदाहरण के लिए, लाइनों की टेक्स्ट फाइल जैसे कि Dog 5 4 7उन्हें उपयोग करके पार्स कर सकते हैं:

var slF, slR: IJclStringList; ai: TList<integer>; s: string; i: integer;
    action: procedure(const Name: string; Const Data: array of integer);

slF := TJclStringList.Create; slF.LoadFromFile('some.txt');
slR := TJclStringList.Create;
for s in slF do begin
    slR.Split(s, ' ', true);
    ai := TList<Integer>.Create;
    try
       for i := 1 to slR.Count - 1 do
           ai.Add(StrToInt(slR[i]));
       action(slR[0], ai.ToArray);
    finally ai.Free; end;
end; 

http://wiki.delphi-jedi.org/wiki/JCL_Help:IJclStringList.Split@string@string@Boolean


3

इससे आपकी समस्या दूर हो जाएगी

interface
   TArrayStr = Array Of string;

implementation

function SplitString(Text: String): TArrayStr;
var
   intIdx: Integer;
   intIdxOutput: Integer;
const
   Delimiter = ';';
begin
   intIdxOutput := 0;
   SetLength(Result, 1);
   Result[0] := ''; 

   for intIdx := 1 to Length(Text) do
   begin
      if Text[intIdx] = Delimiter then
      begin
         intIdxOutput := intIdxOutput + 1;
         SetLength(Result, Length(Result) + 1);
      end
      else
         Result[intIdxOutput] := Result[intIdxOutput] + Text[intIdx];
   end;
end;

क्या आप कृपया कुछ स्पष्टीकरण दे सकते हैं कि कोड क्या करता है? धन्यवाद
पाको

यह गुजरे हुए स्ट्रिंग के माध्यम से चलता है जो सीमांकक कांस्ट की तलाश में है, जब नहीं मिला, तो सरणी पर वर्तमान स्थिति के साथ मिलाएं, जब पाया जाता है, तो गतिशील सरणी में अगली स्थिति के लिए कूदता है
डेनिस

1

विभाजन के लिए मेरा पसंदीदा कार्य:

procedure splitString(delim: char; s: string; ListOfStrings: TStrings);
var temp: string;
    i: integer;
begin
   ListOfStrings.Clear;
   for i:=1 to length(s) do
    begin
      if s[i] = delim then
        begin
          ListOfStrings.add(temp);
          temp := '';
        end
      else
        begin
          temp := temp + s[i];
          if i=length(s) then
             ListOfStrings.add(temp);
        end;
    end;
    ListOfStrings.add(temp);
end;

1
आपके कार्य में अंतिम तत्व छूट गया था
एलिजिनियर

1
आप जोड़ने की जरूरत है ListOfStrings.add(temp);पिछले आइटम जोड़ने के लिए पाश के बाद।
रंसो

नोट के लिए धन्यवाद, मैंने कोड को अन्य ब्लॉक में संपादित किया।
जॉन बो

0

*

//Basic functionality of a TStringList solves this:


uses Classes  //TStringList 
    ,types    //TStringDynArray
    ,SysUtils //StringReplace()
    ;

....

 //--------------------------------------------------------------------------
 function _SplitString(const s:string; const delimiter:Char):TStringDynArray;
  var sl:TStringList;
      i:integer;
  begin
  sl:=TStringList.Create;

  //separete delimited items by sLineBreak;TStringlist will do the job:
  sl.Text:=StringReplace(s,delimiter,sLineBreak,[rfReplaceAll]);

  //return the splitted string as an array:
  setlength(Result,sl.count);
  for i:=0 to sl.Count-1
   do Result[i]:=sl[i];

  sl.Free;
  end;



//To split a FileName (last item will be the pure filename itselfs):

 function _SplitPath(const fn:TFileName):TStringDynArray;
  begin
  result:=_SplitString(fn,'\');
  end;

*


0

NGLG उत्तर का आधार https://stackoverflow.com/a/8811242/6619626 आप निम्न फ़ंक्शन का उपयोग कर सकते हैं:

type
OurArrayStr=array of string;

function SplitString(DelimeterChars:char;Str:string):OurArrayStr;
var
seg: TStringList;
i:integer;
ret:OurArrayStr;
begin
    seg := TStringList.Create;
    ExtractStrings([DelimeterChars],[], PChar(Str), seg);
    for i:=0 to seg.Count-1 do
    begin
         SetLength(ret,length(ret)+1);
         ret[length(ret)-1]:=seg.Strings[i];
    end;
    SplitString:=ret;
    seg.Free;
end;

यह सभी डेल्फी संस्करणों में काम करता है।


0

डेल्फी 2010 के लिए, आपको अपना स्वयं का विभाजन फ़ंक्शन बनाने की आवश्यकता है।

function Split(const Texto, Delimitador: string): TStringArray;
var
  i: integer;
  Len: integer;
  PosStart: integer;
  PosDel: integer;
  TempText:string;
begin
  i := 0;
  SetLength(Result, 1);
  Len := Length(Delimitador);
  PosStart := 1;
  PosDel := Pos(Delimitador, Texto);
  TempText:=  Texto;
  while PosDel > 0 do
    begin
      Result[i] := Copy(TempText, PosStart, PosDel - PosStart);
      PosStart := PosDel + Len;
      TempText:=Copy(TempText, PosStart, Length(TempText));
      PosDel := Pos(Delimitador, TempText);
      PosStart := 1;
      inc(i);
      SetLength(Result, i + 1);
    end;
  Result[i] := Copy(TempText, PosStart, Length(TempText));
end;

आप इसे इस तरह से संदर्भित कर सकते हैं

type
  TStringArray = array of string;
var Temp2:TStringArray;
Temp1="hello:world";
Temp2=Split(Temp1,':')

0
procedure SplitCSV(S:STRING;out SL:TStringList);
var c,commatext:string;
  a,b,up:integer;
begin
   c:=s.Replace(' ','<SPACE>');   //curate spaces

   //first ocurrence of "
   a:=pos('"',c);
   b:=pos('"',c,a+1);
   if (a>0) and (b>0) then
   begin
     commatext:=commatext+copy(c,0,a-1);
     commatext:=commatext+copy(c,a,b-a+1).Replace(',','<COMMA>');   //curate commas
     up:=b+1;
   end
   else
     commatext:=c;

   //while continue discovering "
   while (a>0) and (b>0) do
   begin
     a:=Pos('"',c,b+1);
     b:=pos('"',c,a+1);
     if (a>0) and (b>0) then
     begin
       commatext:=commatext+copy(c,up,a-up);
       commatext:=commatext+copy(c,a,b-a+1).Replace(',','<COMMA>'); //curate commas
       up:=b+1;
     end;
   end;
   //last piece of text end  
   if up<c.Length then
     commatext:=commatext+copy(c,up,c.Length-up+1);

   //split text using CommaText
   sl.CommaText:=commatext;

   sl.Text:=sl.Text.Replace('<COMMA>',',');   //curate commas
   sl.Text:=sl.Text.Replace('<SPACE>',' ');   //curate spaces
end;

उत्तर जो स्पष्ट रूप से और स्पष्ट रूप से समाधान की व्याख्या करते हैं, वे कोड-ओनली की तुलना में बहुत अधिक उपयोगी हैं।
मार्टिना

0
interface

uses
  Classes;

type
  TStringArray = array of string;

  TUtilStr = class
    class function Split(const AValue: string; const ADelimiter: Char = ';'; const AQuoteChar: Char = '"'): TStringArray; static;
  end;


implementation

{ TUtilStr }

class function TUtilStr.Split(const AValue: string; const ADelimiter: Char; const AQuoteChar: Char): TStringArray;
var
  LSplited: TStringList;
  LText: string;
  LIndex: Integer;
begin
  LSplited := TStringList.Create;
  try
    LSplited.StrictDelimiter := True;
    LSplited.Delimiter := ADelimiter;
    LSplited.QuoteChar := AQuoteChar;
    LSplited.DelimitedText := AValue;

    SetLength(Result, LSplited.Count);
    for LIndex := 0 to LSplited.Count - 1 do
    begin
      Result[LIndex] := LSplited[LIndex];
    end;
  finally
    LSplited.Free;
  end;
end;

end.
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.