Question

Delphi - string manipulation

Asked by: nickjfox

Using TMemo I need to look for a phrase and delete the phrase plus two words after the phrase.

So for instance if the phrase is The quick brown fox, the string
"The quick brown fox jumps over the lazy dog"  becomes "the lazy dog"

This Question has been solved and asker verified All Experts Exchange premium technology solutions are available to subscription members.

Subscribe now for full access to Experts Exchange and get

Instant Access to this Solution

  • Plus...
  • 30 Day FREE access, no risk, no obligation
  • Collaborate with the world's top tech experts
  • Unlimited access to our exclusive solution database
  • Never be left without tech help again

Subscribe Now

Asked On
2009-07-04 at 04:48:40ID24543767
Tags

Delphi Pascal

Topic

Delphi Programming

Participating Experts
3
Points
300
Comments
41

Trusted by hundreds of thousands everyday for fast, accurate and reliable tech support.

  • "The time we save is the biggest benefit of Experts Exchange to Warner Bros. What could take multiple guys 2 hours or more each to find is accessed in around 15 minutes on Experts Exchange." Mike Kapnisakis, Warner Bros.
  • "Our team likes having a resource that is more secure than just using Google and most experts using this service really know their stuff. It's nice to look here first versus using Google." Dayna Sellner, Lockheed Martin
  • "Anytime that I've been stumped with a problem, 9 out of 10 times Experts Exchange has either the accepted solution or an open discussion of the potential solution to the problem." Kenny Red, eBay Inc.

See what Experts Exchange can do for you.

Got a question?

We've got the answer.

Experts Exchange has been collecting answers to technology questions since 1996…3 million and counting! If you have a question, chances are we already have your answer.

Screenshot of Experts Exchange Knowledgebase

Need individual assistance?

Our experts are ready to help.

If you can't find the exact answer you're looking for, ask our exclusive community of 50,000 experts. You’ll get a personalized answer from a trusted professional.

Screenshot of Experts Exchange Knowledgebase

Want to learn from the best?

Read articles from industry experts.

Thousands of free tech tips, tricks, how-to’s and tutorials are available in our peer reviewed articles section. See for yourself how smart our experts are, no login required.

Screenshot of an Article

Working on a long term project?

Store your work and research.

Save solutions to your questions, answers you’ve discovered through searching plus helpful articles in your personal knowledgebase for easy future access.

Screenshot of Experts Exchange Knowledgebase

Access the answers to your technology questions today.

Subscribe Now

30-day free trial. Register in 60 seconds.

What Makes Experts Exchange Unique?

Members of the expert community talk about why the experience at Experts Exchange is different than what you will find anywhere else.

Trusted by the world's most respected brands.

image of each brand's logo

Faithfully serving IT professionals since 1996.

Experts Exchange Logo

Try it out and discover for yourself.

Subscribe Now

30-day free trial. Register in 60 seconds.

Related Solutions

  1. Hidden Goodies
    Hi all, If I type =rand() into word and press return it changes to The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jum...
  2. Track Changes
    I want to be able to Track all changes in a Text Box. Old Text: The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumped over the lazy cat. The quick brown fox jumps over...
  3. Need to output every second line in a text file
    Hello all, I need to run a short script of some sort that looks through a text file of a variable sze and take every second line and output this to a new file. The one catch? is the original file cannot be left with a blank line where the line was extracted I was looking at a...
  4. Word macro to convert text
    I have Windows XP with Word 2003. I need a Word macro to convert text. The text may contain superscript numbers like this: The quick brown fox1 jumped over the lazy2 dogs. 1964 The quick brown fox jumped over the lazy dogs.The quick3 brown fox ju1700mped over the lazy d...

Free Tech Articles

  1. WARNING: 5 Reasons why you should NEVER fix a computer for free.
    It is in our nature to love the puzzle. We are obsessed. The lot of us. We love puzzles. We love the challenge. We thrive on finding the answer. We hate disarray. It bothers us deep in our soul. W...
  2. SCCM OSD Basic troubleshooting
    SCCM 2007 OSD is a fantastic way to deploy operating systems, however, like most things SCCM issues can sometimes be difficult to resolve due to the sheer volume of logs to sift through and the dispe...
  3. Migrate Small Business Server 2003 to Exchange 2010 and Windows 2008 R2
    This guide is intended to provide step by step instructions on how to migrate from Small Business Server 2003 to Windows 2008 R2 with Exchange 2010. For this migration to work you will need the fo...
  4. Create a Win7 Gadget
    This article shows you how to create a simple "Gadget" -- a sort of mini-application supported by Windows 7 and Vista. Gadgets can be dropped anywhere on the desktop to provide instant information, ...
  5. Outlook continually prompting for username and password
    There have been a lot of questions recently regarding Outlook prompting for a username and password whilst using Exchange 2007. There are a few reasons why this would happen and I will try to cover t...
  6. Backup Exchange 2010 Information Store using Windows Backup
    There seems to be quite a lot of confusion around the ability to backup Exchange 2010 using the built in Windows Backup feature. This stems from the omission of this feature prior to Exchange 2007 s...

Cloud Class Webinars

  1. Avoiding Bugs in Microsoft Access
    Alison Balter takes and in-depth look at avoiding bugs in Access. In this webinar you will learn about using the immediate window to debug your applications, invoking the debugger, using breakpoints to troubleshoot, stepping through code, setting the next statement to execute, ...
  2. Top 10 Best New Features in Visio 2010
    Scott Helmers gives live demonstrations of the top 10 new features in Visio 2010. This webinar will teach you how to create compelling diagrams by adding shapes to the page with a single click, linking the shapes in a diagram to data in Excel (or SQL Server, or SharePoint), ...
  3. IT Consultant Business Secrets Revealed
    Michael Munger, Experts Exchange tech pro and IT consultant, pulls back the curtain on his very successful businesses and answers question on every IT consultant and business owner should know about. He shares secrets on what he did to solve the 5 most common problems in IT, ...
  4. Disaster Recovery and Business Continuity
    Quest CTO, Mike Billon, gives an overview of the steps involved in building a dunamic disaster recovery plan. Through case studies and an examination of software/hardware tooles for monitoring and testing, you'll gain a better understandin of where you are, where you want ...
  5. Organize Your Visio Diagrams with Containers and Lists
    Scott Helmers uses cross functional flowcharts, wireframe diagrams, data graphic legends and seating charts to teach you: how to ustilize all three new structured diagram components in Visio 2010, the best practices for organizeing shapes in previous version of Visio, how to organize ...
  6. How to Us Objects, Properties, Events and Methods in Microsoft Access
    Alison Dalter gives an in-depbth look at objects, properties, events and methods in Microsoft Access. In this webinar you will learn about using the object browser, referring to objects, working with properties and methods, working with object variables, understanding the ...

Join the Community

Give a Little. Get a Lot.

Join the community of experts here and help other tech pros by answering question in your area of expertise. You can earn FREE access to all Experts Exchange's premium features and resources.

Join the Community

Answers

 

by: Geert_GruwezPosted on 2009-07-04 at 13:23:28ID: 24777901

use the PosEx function to find the phrase
and then again to find the second space, assuming there is spaces after

function FindPhrasePlusTwoWords(aText, aPhrase: string; StartAt: integer = 1): integer;
var p, n: integer;
begin
  Result := 0;
  p := PosEx(aPhrase, aText, StartAt);
  if p > 0 then  
  begin
    n := PosEx(' ', aText, p + Length(aPhrase));
    if n > 0 then 
      Result := Pos(' ', aText, n+1); // Result = pos of space after last word
  end;
end;

                                              
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:

Select allOpen in new window

 

by: nickjfoxPosted on 2009-07-05 at 02:05:50ID: 24779269

OK, thanks. Line10 is Results:=PosEx(  rather than Pos( ?

Also, sorry I've done hardly any work with strings before, but once I have found the position
how do I then delete the word in that position?

Thanks for your patience.



 

by: nickjfoxPosted on 2009-07-05 at 03:53:44ID: 24779538

I thought I found the solution here http://www.delphicorner.f9.co.uk/articles/misc9.htm.

This adds each word of the TMemo line to a string list. I then need to find the index numbers of the words I am looking for and then delete them together with Index numbers +1 and +2.

However the code I used below seems not to populate the string list?

procedure fillstringlist;
var memoline: TStringList; fulltext, wrd: String;
begin
memoline:=TStringList.Create;
while AnsiPos(' ',fulltext)>0 do begin
///while there are spaces continue
wrd:=copy(fulltext,1,Ansipos(' ',fulltext)-1);
///get first word 
memoline.Add(Wrd);
///add it to the TString list
fulltext:=Copy(fulltext,AnsiPos(' ',fulltext)+1,Length(fulltext)-Length(Wrd)+1); 
//take the first word out of the main text
 end;
 if Length(fulltext)>0 then memoline.Add(fulltext);
///check to see nothing is left
end;
                                              
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:

Select allOpen in new window

 

by: aikimarkPosted on 2009-07-05 at 04:56:12ID: 24779710

@nickjfox

Use a variation of the information produced by the Geert routine to create a new memo content.  In fact, the code you posted contains an example.
fulltext:=Copy();

What you do is set the memo text = the text before the start of the found concatenated with the text after the end of the second word.

What you will have to decide is what you want to do if there aren't two words after the searched-for text.

Note: in this version of the function, you will pass two integer variables into the routine that will contain the start of the found text and the position of the space following the second word.

function FindPhrasePlusTwoWords(aText, aPhrase: string; StartAt: integer = 1; FoundStart, FoundEnd: integer): Boolean;
var p, n: integer;
begin
  Result := False;
  p := PosEx(aPhrase, aText, StartAt);
  if p > 0 then  
  begin
    FoundStart := p;
    n := PosEx(' ', aText, p + Length(aPhrase));
    if n > 0 then 
      begin
        FoundEnd := Pos(' ', aText, n+1); 
        Result := True;
      end;
    else
     FoundEnd := p + Length(aPhrase);
  end;
end;
                                              
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:

Select allOpen in new window

 

by: nickjfoxPosted on 2009-07-05 at 08:43:39ID: 24780309

@Aikimark

I get error messages from your function

line1: default value required for FoundEnd
line12:  too many actual parameters

BTW, there are always two words after the phrase. In real life the phrase is always 'passed by' and there  always follows two names.

I need to delete: "passed by XXXXX YYYYY" from the memo line.

 

by: aikimarkPosted on 2009-07-05 at 08:53:33ID: 24780322

oops.  I wrongly placed my two parameters after the optional Startat parameter.  Try this.

function FindPhrasePlusTwoWords(aText, aPhrase: string; FoundStart, FoundEnd: integer; StartAt: integer = 1): Boolean;
var p, n: integer;
begin
  Result := False;
  p := PosEx(aPhrase, aText, StartAt);
  if p > 0 then  
  begin
    FoundStart := p;
    n := PosEx(' ', aText, p + Length(aPhrase));
    if n > 0 then 
      begin
        FoundEnd := Pos(' ', aText, n+1); 
        Result := True;
      end;
    else
     FoundEnd := p + Length(aPhrase);
  end;
end; 
                                              
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:

Select allOpen in new window

 

by: JonasMalmstenPosted on 2009-07-05 at 09:34:38ID: 24780459

ThievingSix provided an easy way to split a string into words while answering your previous question: http://www.experts-exchange.com/Programming/Languages/Pascal/Delphi/Database/Q_24539293.html
However, in this case I think it is easier to just use Pos to locate the whole phrase rather than finding each word.

Here is a slight modification of what Geert Gruwez wrote that does what (I think) you want.

function RemovePhrasePlusTwoWords(aText, aPhrase: string): String;
var
  p, n: integer;
begin
  Result := aText;
  p := Pos(aPhrase, aText);
  if p > 0 then
  begin
    n := PosEx(' ', aText, p + Length(aPhrase) + 1);
    if n > 0 then n := PosEx(' ', aText, n+1);
    Delete(Result, p, n - p + 1);
  end;
end;
 
procedure TForm1.Button1Click(Sender: TObject);
begin
  Memo1.Text := 'The quick brown fox jumps over the lazy dog';
 
  Memo1.Text := RemovePhrasePlusTwoWords(Memo1.Text, 'The quick brown fox');
end;
                                              
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:

Select allOpen in new window

 

by: Geert_GruwezPosted on 2009-07-05 at 11:33:08ID: 24780841

damn it, everybody's extending my code ... looool
nice work guys, i thought everybody would be out like me enjoying the nice weather
i guess some of you didn't get lucky with the weather

 

by: aikimarkPosted on 2009-07-05 at 12:33:40ID: 24781049

c'mon, Geert.  Look at the top of the Delphi leader board.  You won't see me up there.  If I'm going to offer a Delphi solution, I'm probably going to start with some trustworthy source, such as you. :-)

No luck on the weather either.  Rainy today.

 

by: nickjfoxPosted on 2009-07-05 at 13:05:31ID: 24781159

OK everyone, I'm sure it's me to blame - but I couldn't get any of the above to work.

Geert - I get an error message too many parameters line 10, ditto Akimark's revised version. Jonas I get a string of nothing.

The code below splits the relevant memo1 line into a string list, from where I can get the string list index of the relevant words in the phrase.

Now, I just have to figure out how to delete the string list indexed at the 4 points and return the result back into a string, which might well be tomorrow's question.

Anyway, thanks for the help. I'll split the points.



Procedure Deletion;
var  fullstring, wrd: String; ILine: Integer; memoline: TStringList;
begin
for iLine := Form1.Memo1.Lines.Count-1 downto 0 do begin
   fullstring:=TrimLeft(Form1.Memo1.Lines[iLine]);
  if AnsiContainsStr(fullstring,'passed by') then begin
   memoline:=TStringList.Create;
    while (Pos(' ',fullstring)>0) do begin
   wrd:=copy(fullstring,1,Pos(' ',fullstring)-1);
   Memoline.Add(Wrd);
   fullstring:=Copy(fullstring,Pos(' ',fullstring)+1,Length(fullstring)-Length(Wrd)+1);
end;

                                              
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:

Select allOpen in new window

 

by: Geert_GruwezPosted on 2009-07-05 at 13:33:15ID: 24781237

hey guys, just joking
for the asker if you post a remark, don't close it immediately, with a B
i'm on holiday, so i'm slow in answering ...
now lets see if we can earn an A grade

wow, looks like you'r in bad need of some delphi programming advise ...
fwiw, TStringlist.Create and no free ? = memory leak,

so you want to know what words after your text ?
let me code a few minutes i'll get back to you


 

by: Geert_GruwezPosted on 2009-07-05 at 13:55:38ID: 24781296

i would, this is an interesting Q ...

here is where i am at the moment.
I created some helper functions to find positions in the string

function PhraseStart(aPhrase, aHaystack: string; aStartAt: Integer = 1): integer;
begin
  Result := PosEx(UpperCase(aPhrase), UpperCase(aHaystack), aStartAt);
end;
 
function PhraseEnd(aPhrase: string; aStartAt: Integer = 1): integer;
begin
  if aStartAt < 1 then
    aStartAt := 1;
  Result := aStartAt + Length(aPhrase) -1;
end;
 
function NextWordEnd(aText: string; aStartAt: integer = 1): integer;
var n, l: Integer;
  IsLetter: Boolean;
begin
  Result := 0;
  if aStartAt < 1 then
    aStartAt := 1;
  n := 0;
  l := Length(aText);
  repeat
    IsLetter := False;
    if n + aStartAt < l then
    begin
      if Pos(aText[n + aStartAt], WordLetters) > 0 then
        IsLetter := True;
    end;
    if IsLetter then
      n := n + 1;
  until not IsLetter;
end;
 
function NextWordBegin(aText: string; aStartAt: integer = 1): integer;
var n, l: Integer;
  IsLetter, EndOfLine: Boolean;
begin
  Result := 0;
  if aStartAt < 1 then
    aStartAt := 1;
  n := 0;
  l := Length(aText);
  EndOfLine := False;
  repeat
    IsLetter := False;
    if n + aStartAt < l then
    begin
      if Pos(aText[n + aStartAt], WordLetters) > 0 then
        IsLetter := True;
    end else EndOfLine := True;
    if not IsLetter then
      n := n + 1;
  until IsLetter or EndOfLine;
end;

                                              
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:

Select allOpen in new window

 

by: Geert_GruwezPosted on 2009-07-05 at 14:37:49ID: 24781386

here is code (in D2009)

unit Unit1;
 
interface
 
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;
 
type
  TForm1 = class(TForm)
    btnSearch: TButton;
    memLines: TMemo;
    edSearch: TEdit;
    memTests: TMemo;
    edStartAt: TEdit;
    procedure btnSearchClick(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
 
var
  Form1: TForm1;
 
implementation
 
uses StrUtils;
 
{$R *.dfm}
 
const WordLetters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZéèçàùâêûîôäëüïöÿáúíóàèùìò';
 
function PhraseStart(aPhrase, aHaystack: string; aStartAt: Integer = 1): integer;
begin
  Result := PosEx(aPhrase, aHaystack, aStartAt);
end;
 
function PhraseEnd(aPhrase: string; aStartAt: Integer = 1): integer;
begin
  if aStartAt < 1 then
    aStartAt := 1;
  Result := aStartAt + Length(aPhrase) -1;
end;
 
function NextWordEnd(aText: string; aStartAt: integer = 1): integer;
var n, l: Integer;
  IsLetter: Boolean;
begin
  Result := 0;
  if aStartAt < 1 then
    aStartAt := 1;
  n := 0;
  l := Length(aText);
  repeat
    IsLetter := False;
    if n + aStartAt < l then
    begin
      if Pos(aText[n + aStartAt], WordLetters) > 0 then
        IsLetter := True;
    end;
    if IsLetter then
      n := n + 1;
  until not IsLetter;
  if n > 0 then
    Result := aStartAt + n;
end;
 
function NextWordBegin(aText: string; aStartAt: integer = 1): integer;
var n, l: Integer;
  IsLetter, EndOfLine: Boolean;
begin
  Result := 0;
  if aStartAt < 1 then
    aStartAt := 1;
  n := 0;
  l := Length(aText);
  EndOfLine := False;
  repeat
    IsLetter := False;
    if n + aStartAt < l then
    begin
      if Pos(aText[n + aStartAt], WordLetters) > 0 then
        IsLetter := True;
    end else EndOfLine := True;
    if not IsLetter then
      n := n + 1;
  until IsLetter or EndOfLine;
  if EndOfLine then
    Result := -1
  else if n > 0 then
    Result := aStartAt + n;
end;
 
procedure TForm1.btnSearchClick(Sender: TObject);
var searchText, memText, origText: string;
  sa: integer; // start at
  ps: integer; // start of phrase
  pe: integer; // end of phrase (last letter pos)
  wb, wb2: integer; // beginning of first and second word
  we, we2: integer; // end of first and second word
begin
  searchText := UpperCase(Trim(edSearch.Text)); // Make all uppercase (has no bearings on positions)
  origText := memLines.Lines.Text;
  memText := UpperCase(origText);
  sa := StrToInt(edStartAt.Text);
  if searchText <> '' then
  begin
    ps := PhraseStart(searchText, memText, sa);
    pe := PhraseEnd(searchText, ps);
    // now we need to find the beginning of the next word
    // it's possibly on the next line
    wb := NextWordBegin(memText, pe+1);
    // if we found a word, let's continue
    if wb > 0 then
    begin
      we := NextWordEnd(memText, wb);
      if we > 0 then
      begin
        wb2 := NextWordBegin(memText, we);
        if wb2 > 0 then
        begin
          we2 := NextWordEnd(memText, wb2);
          if we2 > 0 then
          begin
            // now we have all needed positions ...
            // Extract all items to other memo and delete in original memo
 
            memTests.Lines.Add('phrase: "' + Copy(origText, ps, pe-ps+1) + '"');
            memTests.Lines.Add('word 1 after phrase : "' + Copy(origText, wb, we-wb) + '"');
            memTests.Lines.Add('word 2 after phrase : "' + Copy(origText, wb2, we2-wb2) + '"');
            memTests.Lines.Add('phrase + 2 words : "' + Copy(origText, ps, we2-ps) + '"');
            memTests.Lines.Add('------ modified text below ------');
            Delete(origText, ps, we2-ps);
            memTests.Lines.Add(origText);
            memTests.Lines.Add('------ modified text above ------');
            edStartAt.Text := IntToStr(we2);
 
            // you would only need the following code
            // Delete(origText, ps, we2-ps);
            // memTests.Lines.Add(origText);
          end;
        end;
      end;
    end;
  end else
    ShowMessage('Look for an empty string in the wardrobe ... !');
end;
 
end.
 
 
-- dfm --
object Form1: TForm1
  Left = 0
  Top = 0
  Caption = 'Form1'
  ClientHeight = 673
  ClientWidth = 726
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'Tahoma'
  Font.Style = []
  OldCreateOrder = False
  PixelsPerInch = 96
  TextHeight = 13
  object btnSearch: TButton
    Left = 24
    Top = 28
    Width = 75
    Height = 25
    Caption = 'btnSearch'
    TabOrder = 0
    OnClick = btnSearchClick
  end
  object memLines: TMemo
    Left = 112
    Top = 58
    Width = 585
    Height = 137
    Lines.Strings = (
      
        'Using TMemo I need to look for a phrase and delete the phrase pl' +
        'us two words after the phrase.'
      ''
      'So for instance if the phrase is The quick brown fox, the string'
      
        '"The quick brown fox jumps over the lazy dog"  becomes "the lazy' +
        ' dog"')
    TabOrder = 1
  end
  object edSearch: TEdit
    Left = 112
    Top = 32
    Width = 241
    Height = 21
    TabOrder = 2
    Text = 'The quick brown fox'
  end
  object memTests: TMemo
    Left = 112
    Top = 201
    Width = 585
    Height = 456
    TabOrder = 3
  end
  object edStartAt: TEdit
    Left = 576
    Top = 31
    Width = 121
    Height = 21
    Alignment = taRightJustify
    NumbersOnly = True
    TabOrder = 4
    Text = '1'
  end
end

                                              
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
141:
142:
143:
144:
145:
146:
147:
148:
149:
150:
151:
152:
153:
154:
155:
156:
157:
158:
159:
160:
161:
162:
163:
164:
165:
166:
167:
168:
169:
170:
171:
172:
173:
174:
175:
176:
177:
178:
179:
180:
181:
182:
183:
184:
185:
186:
187:
188:
189:
190:
191:
192:
193:
194:
195:
196:
197:
198:
199:
200:
201:
202:
203:
204:
205:
206:
207:
208:
209:
210:
211:
212:
213:
214:
215:
216:
217:
218:
219:

Select allOpen in new window

 

by: Geert_GruwezPosted on 2009-07-05 at 14:38:31ID: 24781388

it will need to be searched 2 times in this example
the edit in the top right get's adjusted after every search

 

by: Geert_GruwezPosted on 2009-07-05 at 14:40:04ID: 24781393

this coding is not built for speed, i does the job,
russel libby is a lot better with fast string manipulations ...

 

by: aikimarkPosted on 2009-07-05 at 14:50:51ID: 24781415

@Geert

* Why look at letters when you could just look for the next space and back up one?

* If I were seeing this for the first time, I might ask if there shouldn't be a parameter that specifies the number of nextwords to find rather than executing the NextWordBegin twice.

 

by: Geert_GruwezPosted on 2009-07-05 at 15:19:16ID: 24781483

looking at the sample code from the asker, i'm guessing he is new to delphi
that's why this way

finding the next word is not allways easy, what about a comma,
this code has no problem with 3 or 4 spaces in between words
(it does have other problems)

 

by: aikimarkPosted on 2009-07-05 at 15:43:31ID: 24781566

@Geert

That is another question for nickjfox...are we including other punctuation as delimiters or just spaces?

I think there should probably be a mixture of Pos() and single character inspection.  When looking for the start of the next word, use a single character inspection for not-a-space.

Some delimiter rules can get VERY tricky -- when is an apostrophe used as a contraction versus a quote?  Things get even trickier when we consider multiple language support.

Another unknown is the cleanliness of the text.  Is it messy?  Are sentences well formed and punctuated properly?

 

by: Geert_GruwezPosted on 2009-07-05 at 16:35:41ID: 24781695

all that can only be solved with a very good parser ...
but i don't think this Q will see one posted here (at least not for points)

 

by: aikimarkPosted on 2009-07-05 at 17:28:06ID: 24781802

speaking of parsers...what about a TRegExp solution?  If you could get the pattern right it would be the minimum amount of Delphi code.  However, it wouldn't perform very well and would suffer the same flexibility problems and messiness issues we've been discussing.

 

by: nickjfoxPosted on 2009-07-06 at 03:12:48ID: 24783780

I'm sorry, I didn't mean to offend anyone by giving a B but it was hard to give an A when I couldn't get the solutions to work. The reason I gave the points was because I did find a solution, final code below.
It's probably rubbish but it does do the job. Anyway, thanks again.

Procedure DeletePhrasePlusTwo;
var  oldtext, wrd, newtext: String; ILine, i, phraseposition: Integer; memoline: TStringList;
begin
for iLine := Form1.Memo1.Lines.Count-1 downto 0 do begin
   oldtext:=TrimLeft(Form1.Memo1.Lines[iLine]);
   ///look for phrase//
  if AnsiContainsStr(oldtext,'passed by') then begin  
   memoline:=TStringList.Create;
   ///if found, parse text to Stringlist
    while (Pos(' ',oldtext)>0) do begin     
   wrd:=copy(oldtext,1,Pos(' ',oldtext)-1);
   Memoline.Add(Wrd);
   oldtext:=Copy(oldtext,Pos(' ',oldtext)+1,Length(oldtext)-Length(Wrd)+1);
end;
 
   if Length(oldtext)>0 then memoline.Add(oldtext); //check text is //finished
 
  phraseposition:=Memoline.IndexOf('passed');   ///get position of //'passed'
  if Memoline[phraseposition+1]='by' then begin  ///check that ///'passed' is followed by 'by'
 
 for i:=  0 to 3 do
   Memoline.Delete(phraseposition);  ////delete 'passed', 'by' and two //words that follow
 
 for I := 0 to Memoline.Count - 1 do  ///get list back to string 
  newtext := newtext +' '+ memoline[i]; 
 
   memoline.Free;
 
  end;
 end;
  end;
end;
 
 
end.

                                              
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:

Select allOpen in new window

 

by: Geert_GruwezPosted on 2009-07-06 at 04:18:28ID: 24784064

no offence taken, but let me point out, the code has a memory leak ...
i just redid the indentation and found the TStringList.Create on indent = 3 and free on indent = 4

basically you only free the stringlist when you find the word 'by'

are you a beginner with Delphi ?


Procedure DeletePhrasePlusTwo;
var  oldtext, wrd, newtext: String; ILine, i, phraseposition: Integer; memoline: TStringList;
begin
  // indent = 1
  for iLine := Form1.Memo1.Lines.Count-1 downto 0 do
  begin
    // indent = 2
    oldtext:=TrimLeft(Form1.Memo1.Lines[iLine]);
    ///look for phrase//
    if AnsiContainsStr(oldtext,'passed by') then
    begin
      // indent = 3
      memoline:=TStringList.Create;
      ///if found, parse text to Stringlist
      while (Pos(' ',oldtext)>0) do
      begin
        wrd:=copy(oldtext,1,Pos(' ',oldtext)-1);
        Memoline.Add(Wrd);
        oldtext:=Copy(oldtext,Pos(' ',oldtext)+1,Length(oldtext)-Length(Wrd)+1);
      end;
 
      if Length(oldtext)>0 then
        memoline.Add(oldtext); //check text is //finished
 
      phraseposition:=Memoline.IndexOf('passed');   ///get position of //'passed'
 
      if Memoline[phraseposition+1]='by' then
      begin  ///check that ///'passed' is followed by 'by'
        // indent = 4
        for i:=  0 to 3 do
          Memoline.Delete(phraseposition);  ////delete 'passed', 'by' and two //words that follow
 
        for I := 0 to Memoline.Count - 1 do  ///get list back to string
          newtext := newtext +' '+ memoline[i];
 
        memoline.Free;
      end;
    end;
  end;
end;

                                              
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:

Select allOpen in new window

 

by: nickjfoxPosted on 2009-07-06 at 07:16:43ID: 24785403

@ Geert, thanks, I'll take your advice re the memory leak
@ aikimark, I awarded the points yesterday

 

by: aikimarkPosted on 2009-07-06 at 08:09:58ID: 24785925

@nickjfox

I know, but I unaccepted your selections thinking that Geert could supply a satisfactory answer.  I didn't know that you had found your solution separately.

 

by: Geert_GruwezPosted on 2009-07-06 at 08:58:53ID: 24786502

your solution is not very flexible ...
let me explain :
it only works on Form1
it's only for Ansi (D2009 is unicode)
your cleanup is not error proof (you don't use try finally)
it only works for the phrase 'passed by'
it only works if words are separated by spaces (EOL and LF) ?

 

by: nickjfoxPosted on 2009-07-06 at 10:21:10ID: 24787284

@Geert

I don't want marks for my code. How many times do I have to say my code is crap and I don't know what I am doing.

I am a beginner. Although you keep asking whether I am a beginner, you can get the clue from the top where it says:

"Author: nickjfox, Limited Member
Beginner on this subject. "

 

by: nickjfoxPosted on 2009-07-06 at 10:24:25ID: 24787323

I've spent more time on this site looking for a solution than doing my own solution myself

 

by: nickjfoxPosted on 2009-07-06 at 10:24:48ID: 24787325

And I am a beginner as it says at the top of the page

 

by: aikimarkPosted on 2009-07-06 at 10:45:46ID: 24787479

@nickjfox

I appologize for this poor experience.  Please reconsider.  

Your earlier experience (beginner status) comment highlights one of the shortcomings with the EE member profiles that we are currently working to fix.  Most subject matter experts at EE don't think that it is reliable and usually ignore it.  In this case, we should have explicitly asked you if you needed help with the code that we posted.  

This non-reliance on questioner experience can cut both ways, so I usually assume that the questioner has some experience.  I've angered some questioners by asking them if they were beginners, when they were just non-native English speakers.  It's a tough call.

 

by: nickjfoxPosted on 2009-07-06 at 10:58:02ID: 24787588

@ModernMatt

[quote]I  I am sure if you had posted the original code you used to resolve this matter when you closed the question yesterday, everything would have made complete sense and this would have been less of an issue.[/quote]

Do you people actually see threads written by the asker?

Read  24781159



 

by: nickjfoxPosted on 2009-07-06 at 11:17:23ID: 24787761

Have I been banned?

 

by: aikimarkPosted on 2009-07-06 at 11:21:52ID: 24787807

@nickjfox

I hope not.  You really didn't have to award ANY points to ANY expert in this thread.  If it will make you feel any better, we can do this for you.  You were working independently towards a solution and you found yours first.  I really didn't expect any points when I reopened the question, since I thought that Geert was already close to posting the best solution.

As Geert commented, this was an interesting problem to be solved.  I only reopened the question because I thought you weren't satisfied.  This action might have been the opening action to this 'can of worms'.  If so, I'm very sorry to you, the other experts participating in this thread, and to the mods/admins who have been brought into this.

20120131-EE-VQP-002

3 Ways to Join

30-Day Free Trial

The Experts

98% positive feedback on 31,087 answers since March 2000. angeliii is a Microsoft Most Valuable Professional for his work with MS SQL Server & Develoment.

He has also proven his knowledge of Visual Basic Programming, PHP Scripting and Oracle Databases.

The Experts

97% positive feedback on 10,752 answers since July 2000. lrmoore has more than 18 years experience in the networking industry.

The six-time Mircosoft MVPs specialties include firewalls, virtual private networking, and network management.

Testimonials

"...and excellent source for support... Kind of like having your very own IT dept." Electriciansnet

Testimonials

"I was apprehensive at signing up at first. However... it has already made my life as an IT administrator much easier." JaCrews

Testimonials

"WOW! You guys have great, active, and knowledgeable people on here." moore50

Business Clients

Business Clients

In the Press

"If you’ve got a question... Experts Exchange can supply an answer.”

In the Press

"...an invaluable aid for both IT professionals and those who require tech support."

In the Press

"where IT professionals provide quick answers on just about any topic"

Business Account Plans

Loading Advertisement...