سؤال

I'm parsing a text file that contains IP address and ports. The IP address and port combinations are separated with one or more TABs or SPACEs or both.

Sample of the occurrence in the text file is like this:

121.78.195.165 8888

I need to match this entire text and return each match with the TAB(s) or SPACE(s) replaced with ":" so that it returns this:

121.78.195.165:8888

This would have been easy if the match was returned with the SPACE or TAB embedded in it, but instead the match is returned without the SPACE(s) or TAB(s) sometimes. Sometimes there's just a space.

eg. Sometimes like this:

121.78.195.1658888

and others like this:

121.78.195.165 8888

The variation above is dependent on whether there are SPACEs, TABs or a combination of both and how many in the source text.

I'm using TPerlRegex in Delphi like this:

  regex := TPerlRegEx.Create;
  try
    regex.Options := [preMultiLine];
    regex.regex :=
      '\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)[\s\t]+\d{2,5}\b';
    regex.Study;

    regex.Subject := StringOf(buf);

    if regex.Match then
    begin

      regex.Replacement := ':';


      s := regex.MatchedText; // <---- Need this to be '121.78.195.165:8888'

      ShowMessage(s);  
    end;

  finally
    regex.Free;
  end;

So my question is more about how to use the Regex engine to do replacement of the TAB(s) or SPACE(s) that appear after the IP address and before the Port.

TIA.

هل كانت مفيدة؟

المحلول

You can use something like this (edited for XE2 TPerlRegEx compatibility):

var
  Regex: TPerlRegEx;
  ResultString: string;
begin
  Regex := TPerlRegEx.Create;
  try
    Regex.RegEx := '\b((?:[0-9]{1,3}\.){3}[0-9]{1,3})\s(.*)';
    Regex.Options := [];
    Regex.State := [preNotEmpty];
    Regex.Subject := SubjectString;
    Regex.Replacement := '\1:\2';
    Regex.ReplaceAll;
    ResultString := Regex.Subject;
  finally
Regex.Free;
  end;
end;

Tested with the following values:

85.39.138.58 151
187.39.55.23 399
80.14.5.209 1424
80.14.6.217 1424
1.1.135.73 1464
80.14.5.209 135
80.14.7.2 1392
187.39.55.100 399
67.78.18.222 1472

Results:

85.39.138.58:151
187.39.55.23:399
80.14.5.209:1424
80.14.6.217:1424
1.1.135.73:1464
80.14.5.209:135
80.14.7.2:1392
187.39.55.100:399
67.78.18.222:1472

نصائح أخرى

If I'm understanding you, this replacement should work:

Find what: \b((?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))(?:[\s\t:]*)(\d{2,5})\b

Replace with: $1:$2

Try it here: http://regex101.com/r/yB1mQ8

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top