【问题标题】:Getting the whole word (link) from a phrase, when I know some of it当我知道一些短语时,从短语中获取整个单词(链接)
【发布时间】:2011-08-30 08:58:10
【问题描述】:

假设我有一个字符串:Go to this page: @987654321@,我有一个字符串page。我想创建一个这样的函数:

MyBoolean := IsLink('Go to this page: http://mysite.com/?page=1','page',sLink); 
// sLink is a Var, so it would return http://mysite.com/?page=1

基本上它应该检查单词“page”是否是链接的一部分。

但是我就是想不通。有什么建议吗?

【问题讨论】:

  • 字符串是否总是包含第一次出现的“page”?或者换句话说:字符串的格式总是Go to this page: link ?
  • @NGLN - 不,并非总是如此,它可以是任何短语

标签: string delphi substring text-parsing


【解决方案1】:

你可以这样做

function GetLinkContaining(const Str, SubStr: string; out URL: string): boolean;
const
  ValidURLSpecialChars = ['.', ':', '/', '?', '=', '&', '%'];
  Prefixes: array[0..4] of string = ('http://', 'https://', 'ftp://', 'mailto:',
    'www.');

  function IsValidURLChar(const Char: char): boolean;
  begin
    result := IsLetterOrDigit(Char) or (Char in ValidURLSpecialChars);
  end;

var
  SubStrPos: integer;
  Start, &End: integer;
  i: Integer;
  URLBegin: integer;
begin
  result := false;

  URLBegin := 0;
  for i := low(Prefixes) to High(Prefixes) do
  begin
    URLBegin := Pos(Prefixes[i], Str);
    if URLBegin > 0 then
      break;
  end;
  if URLBegin = 0 then Exit(false);

  SubStrPos := PosEx(SubStr, Str, URLBegin);
  if SubStrPos = 0 then Exit(false);

  Start := SubStrPos;
  for i := SubStrPos - 1 downto 1 do
    if IsValidURLChar(Str[i]) then
      dec(Start)
    else
      break;
  &End := SubStrPos + length(SubStr);
  for i := SubStrPos + length(SubStr) to length(Str) do
    if IsValidURLChar(Str[i]) then
      inc(&End)
    else
      break;
  URL := Copy(Str, Start, &End - Start);
  result := true;
end;

测试它:

procedure TForm1.FormCreate(Sender: TObject);
var
  s: string;
begin
  if GetLinkContaining('Go to this page: http://mysite.com/?page=1 (right now!)',
    'page', s) then
    ShowMessage(s);
  if GetLinkContaining('This is my favourite site (www.bbc.co.uk).', 'bbc', s) then
    ShowMessage(s);        
end;

【讨论】:

  • 完美!你到底是怎么知道的?太棒了!
  • 仅仅因为您可以使用&End 作为标识符并不意味着这是一件好事。
  • @David:别这么死板! ;)
  • @Andreas - 是否可以让这个函数不区分大小写?
  • @Jeff:是的,这很容易。将Pos(Prefixes[i], Str); 替换为Pos(AnsiLowerCase(Prefixes[i]), AnsiLowerCase(Str));,将PosEx(SubStr, Str, URLBegin) 替换为PosEx(AnsiLowerCase(SubStr), AnsiLowerCase(Str), URLBegin)
【解决方案2】:

要检查“页面”是否是字符串的一部分,您可以使用函数 Pos。

function Pos(Str, Source : string): integer;

Pos 返回一个整数,指定一个字符串在另一个字符串中第一次出现的位置。

Pos 查找 Str 在 Source 中第一次完全出现。如果找到,则将 Str 中第一个字符在 Source 中的字符位置作为整数值返回,否则返回 0。Pos 区分大小写。所以你必须处理大写和小写的情况。

要提取 URL(也许)并不那么容易,您必须定义更多条件。如果 URL 始终位于字符串的末尾,则可以从 http 上复制所有内容(也可以使用 Pos 和 Copy!)

【讨论】:

    【解决方案3】:

    在更强大的字符串匹配算法中,有regular expressions。它们允许非常复杂的匹配,而无需编写太多代码,尽管掌握它们可能需要一点时间。最新版本的 Delphi 已经有正则表达式库,但您也可以找到一些早期版本的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-09-18
      • 1970-01-01
      • 2013-07-09
      • 1970-01-01
      相关资源
      最近更新 更多