2011-02-09 9 views
8

का उपयोग कर एक टेक्स्ट फ़ाइल से स्ट्रिंग निकालें मैं 2 delimiters का उपयोग कर एक पाठ फ़ाइल से एक स्ट्रिंग निकालने की कोशिश कर रहा हूँ। एक शुरू करने के लिए और एक रोकने के लिए।2 delimiters

उदाहरण:

Hi my name is$John and I'm happy/today 

मैं क्या करने की जरूरत एक समारोह है कि $ और / के बीच स्ट्रिंग वापसी होगी कॉल करने के लिए है। मैं हर जगह देख रहा हूं लेकिन मुझे कुछ उपयोगी नहीं लगता है और मैं प्रोग्रामिंग के लिए नया हूं।

उत्तर

11

आप Pos और Copy साथ यह कर सकते हैं:

function ExtractText(const Str: string; const Delim1, Delim2: char): string; 
var 
    pos1, pos2: integer; 
begin 
    result := ''; 
    pos1 := Pos(Delim1, Str); 
    pos2 := Pos(Delim2, Str); 
    if (pos1 > 0) and (pos2 > pos1) then 
    result := Copy(Str, pos1 + 1, pos2 - pos1 - 1); 
end; 
+16

'Delim1' के स्थान के बाद' Delim2' शुरू करने के लिए ['PosEx'] (http://docwiki.embarcadero.com/VCL/en/StrUtils.PosEx) का उपयोग करें। –

+0

@Rob: हाँ, यह प्रदर्शन में वृद्धि करेगा। –

+0

धन्यवाद बिल्कुल मुझे क्या चाहिए !! – Gab

10

मैं इसे इस तरह कुछ करना चाहते हैं:

function ExtractDelimitedString(const s: string): string; 
var 
    p1, p2: Integer; 
begin 
    p1 := Pos('$', s); 
    p2 := Pos('/', s); 
    if (p1<>0) and (p2<>0) and (p2>p1) then begin 
    Result := Copy(s, p1+1, p2-p1-1); 
    end else begin 
    Result := '';//delimiters not found, or in the wrong order; raise error perhaps 
    end; 
end; 
+0

बिल्कुल वही दूसरा प्राप्त करें। यह बहुत मजेदार है। –

+0

@ एंड्रियास कूल वास्तव में –

4

बकवाद, आप एक TFileStream वर्ग का उपयोग कर यह करने के लिए एक समारोह में लिख सकते हैं , और Copy और Pos फ़ंक्शंस।

इस नमूने देखें:

uses 
    Classes, 
    SysUtils; 

function ExtractString(Const FileName: TFileName;Const IDel,FDel : AnsiString) : AnsiString; 
Var 
FileStream : TFileStream; 
i,f  : Integer; 
begin 
    FileStream:= TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite); //oopen the file 
    try 
    try 
     SetLength(Result, FileStream.Size); //set the size of the string 
     FileStream.Read(Pointer(Result)^, FileStream.Size);//read the content into a string 
     i:=Pos(IDel,Result);//search the initial delimiter 
     f:=Pos(FDel,Result);//search the final delimiter 
     Result:=Copy(Result,i+1,f-i-1); //extract the value between the delimiters 
    except 
     Result := ''; 
     raise; 
    end; 
    finally 
    FileStream.Free; 
    end; 
end; 

और इस तरह से

ExtractString('your_file_name','$','/'); 
+0

सेटलेथेंथ + के बजाय, पढ़ें, आप एक TMemoryStream का उपयोग भी कर सकते हैं, फिर LoadFromFile() फिर SetString (परिणाम, PAnsiChar (MemoryStream.Memory), MemoryStream.Size); –

2

दोनों सीमांकक मान लिया जाये कि में उपयोग अपनी पोस्ट के अनुसार एकल वर्ण हैं:

function ExtractDelimitedValueFromFile(const aFilename: String; 
             const aOpenDelim: Char; 
             const aCloseDelim: Char; 
             var aValue: String): Boolean; 
var 
    i: Integer; 
    strm: TStringStream; 
    delimStart: Integer; 
    delimEnd: Integer; 
begin 
    result  := FALSE; 
    aValue  := ''; 
    delimStart := -1; 
    delimEnd := -1; 

    strm := TStringStream.Create; 
    try 
    strm.LoadFromFile(aFileName); 

    for i := 1 to strm.Size do 
    begin 
     if (delimStart = -1) and (strm.DataString[i] = aOpenDelim) then 
     delimStart := i 
     else if (delimStart <> -1) and (strm.DataString[i] = aCloseDelim) then 
     delimEnd := i; 

     result := (delimStart <> -1) and (delimEnd <> -1); 
     if result then 
     begin 
     aValue := Copy(strm.DataString, delimStart + 1, delimEnd - delimStart - 1); 
     BREAK; 
     end; 
    end; 

    finally 
    strm.Free; 
    end; 
end; 

उपयोग:

var 
    str: String; 
    begin 
    if ExtractDelimitedValueFromFile('path\filename.ext', '$', '/', str) then 
     // work with str 
    else 
     // delimited value not found in file 
    end; 
3

नए डेल्फी के आप इसे इस तरह से कर सकते हैं में .. (Yay)

program Project40; {$APPTYPE CONSOLE} 

uses RegularExpressions; 

const 
    str = 'Is$John and I''m happy/today'; 

function GetStr(const aStr: string): string; 
begin 
    Result := TRegEx.Match(aStr, '\$.*/').Value; 
    Result := Copy(Result, 2, Length(Result) - 2); 
end; 

begin 
    Writeln(GetStr(str)); 
    ReadLn; 
end. 
+0

नियमित अभिव्यक्तियों के लिए सबसे अच्छा उपयोग नहीं है, लेकिन बॉक्स के बाहर सोचने के लिए +1 है। – arthurprs

10

ऊपर कार्यों अगर 2 पाठ भी 1 पैटर्न से पहले दिखाई दे रहा है काम नहीं करेगा ...

आप PosEx()Pos() के बजाय का उपयोग करना चाहिए:

आप स्थिति और कॉपी के साथ यह कर सकते हैं:

function ExtractText(const Str: string; const Delim1, Delim2: string): string; 
var 
    pos1, pos2: integer; 
begin 
    result := ''; 
    pos1 := Pos(Delim1, Str); 
    if pos1 > 0 then begin 
    pos2 := PosEx(Delim2, Str, pos1+1); 
    if pos2 > 0 then 
     result := Copy(Str, pos1 + 1, pos2 - pos1 - 1); 
    end; 
end; 
7

सभी

function ExtractText(const Str: string; const Delim1, Delim2: string): TStringList; 
var 
    c,pos1, pos2: integer; 
begin 
    result:=TStringList.Create; 
    c:=1; 
    pos1:=1; 

    while pos1>0 do 
    begin 
    pos1 := PosEx(Delim1, Str,c); 
    if pos1 > 0 then begin 
     pos2 := PosEx(Delim2, Str, pos1+1); 
    if pos2 > 0 then 
     result.Add(Copy(Str, pos1 + length(delim1), pos2 - (length(delim1) + pos1))); 
     c:=pos1+1; 
    end; 

    end; 
end; 
+0

कई घटनाओं को संभालने का अच्छा विचार है, लेकिन यह फ़ंक्शन के भीतर ऑब्जेक्ट बनाने के लिए एक अच्छा डिज़ाइन नहीं है - कॉलिंग कोड को इसे बनाए बिना ऑब्जेक्ट को मुक्त करना प्रबंधित करना चाहिए।स्ट्रिंगलिस्ट को कॉलिंग कोड द्वारा बनाया और प्रबंधित किया जाना चाहिए, और संदर्भ द्वारा पारित किया जाना चाहिए। – Argalatyr

+0

मैं प्रोग्रामिंग के लिए नया हूँ। बस विचार साझा करना। शायद, कोई इसे ठीक कर सकता है। – poetra

संबंधित मुद्दे