代码之家  ›  专栏  ›  技术社区  ›  Rich

如何在文本字符串中提取短语和单词?

  •  2
  • Rich  · 技术社区  · 17 年前

    我有一个搜索方法,它接收用户输入的字符串,在每个空格字符处对其进行拆分,然后根据分隔词列表继续查找匹配项:

    string[] terms = searchTerms.ToLower().Trim().Split( ' ' );
    

    现在我有了一个更进一步的要求:能够通过双引号分隔符来搜索短语。因此,如果提供的搜索条件是:

    “一行”文本

    搜索将匹配出现的“一行”和“文本”,而不是四个单独的词[打开和关闭双引号也需要在搜索前删除]。

    我怎样才能在C中实现这一点?我假设正则表达式是可行的,但是没有太多的涉猎,所以不知道它们是否是最好的解决方案。

    如果您需要更多信息,请询问。事先谢谢你的帮助。

    6 回复  |  直到 10 年前
        1
  •  2
  •   Drew Noakes    17 年前

    这是一个regex模式,它将返回名为“”的组中的匹配项。 term “:

    ("(?<term>[^"]+)"\s*|(?<term>[^ ]+)\s*)+
    

    所以对于输入:

    "a line" of text
    

    输出项由' 学期 '组将是:

    a line
    of
    text
    
        2
  •  1
  •   Robban    17 年前

    正则表达式绝对是一种…

    您应该查看此msdn链接以获取有关regex类的一些信息: http://msdn.microsoft.com/en-us/library/system.text.regularexpressions.regex.aspx

    下面是学习一些正则表达式语法的极好链接: http://www.radsoftware.com.au/articles/regexlearnsyntax.aspx

    然后,为了添加一些代码示例,您可以沿着这些行做一些事情:

    string searchString = "a line of";
    
    Match m = Regex.Match(textToSearch, searchString);
    

    或者,如果您只想确定字符串是否包含匹配项:

    bool success = Regex.Match(textToSearch, searchString).Success;
    
        3
  •  1
  •   Craig Angus karan    17 年前

    在此处使用正则表达式生成器

    http://gskinner.com/RegExr/

    您将能够根据需要对正则表达式进行显示

        4
  •  1
  •   xoxo    17 年前

    使用正则表达式…

    string texttosearchin=“”一行“text”;
    字符串结果=regex.match(texttosearchin,“(?”<=“).*?(?=“)”)。值;

    或者如果不止一个,把它放到一个匹配的集合中…

    matchCollection allPhrases=regex.matches(texttosearchin,“(?)* =“”?*??=“”);

        5
  •  0
  •   Rob Cowell    17 年前

    这个 Knuth-Morris-Pratt (kmp算法)被认为是在字符串中查找子字符串的最快算法(从技术上讲,不是字符串,而是字节数组)。

    using System.Collections.Generic;
    
    namespace KMPSearch
    {
        public class KMPSearch
        {
            public static int NORESULT = -1;
    
            private string _needle;
            private string _haystack;
            private int[] _jumpTable;
    
            public KMPSearch(string haystack, string needle)
            {
                Haystack = haystack;
                Needle = needle;
            }
    
            public void ComputeJumpTable()
            {
                //Fix if we are looking for just one character...
                if (Needle.Length == 1)
                {
                    JumpTable = new int[1] { -1 };
                }
                else
                {
                    int needleLength = Needle.Length;
                    int i = 2;
                    int k = 0;
    
                    JumpTable = new int[needleLength];
                    JumpTable[0] = -1;
                    JumpTable[1] = 0;
    
                    while (i <= needleLength)
                    {
                        if (i == needleLength)
                        {
                            JumpTable[needleLength - 1] = k;
                        }
                        else if (Needle[k] == Needle[i])
                        {
                            k++;
                            JumpTable[i] = k;
                        }
                        else if (k > 0)
                        {
                            JumpTable[i - 1] = k;
                            k = 0;
                        }
    
                        i++;
                    }
                }
            }
    
            public int[] MatchAll()
            {
                List<int> matches = new List<int>();
                int offset = 0;
                int needleLength = Needle.Length;
                int m = Match(offset);
    
                while (m != NORESULT)
                {
                    matches.Add(m);
                    offset = m + needleLength;
                    m = Match(offset);
                }
    
                return matches.ToArray();
            }
    
            public int Match()
            {
                return Match(0);
            }
    
            public int Match(int offset)
            {
                ComputeJumpTable();
    
                int haystackLength = Haystack.Length;
                int needleLength = Needle.Length;
    
                if ((offset >= haystackLength) || (needleLength > ( haystackLength - offset))) 
                    return NORESULT;
    
                int haystackIndex = offset;
                int needleIndex = 0;
    
                while (haystackIndex < haystackLength)
                {
                    if (needleIndex >= needleLength)
                        return haystackIndex;
    
                    if (haystackIndex + needleIndex >= haystackLength)
                        return NORESULT;
    
                    if (Haystack[haystackIndex + needleIndex] == Needle[needleIndex])
                    {
                        needleIndex++;
                    } 
                        else
                    {
                        //Naive solution
                        haystackIndex += needleIndex;
    
                        //Go back
                        if (needleIndex > 1)
                        {
                            //Index of the last matching character is needleIndex - 1!
                            haystackIndex -= JumpTable[needleIndex - 1];
                            needleIndex = JumpTable[needleIndex - 1];
                        }
                        else
                            haystackIndex -= JumpTable[needleIndex];
    
    
                    }
                }
    
                return NORESULT;
            }
    
            public string Needle
            {
                get { return _needle; }
                set { _needle = value; }
            }
    
            public string Haystack
            {
                get { return _haystack; }
                set { _haystack = value; }
            }
    
            public int[] JumpTable
            {
                get { return _jumpTable; }
                set { _jumpTable = value; }
            }
        }
    }
    

    用途:

    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Reflection;
    namespace KMPSearch
    {
        class Program
        {
            static void Main(string[] args)
            {
                if (args.Length != 2)
                {
                    Console.WriteLine("Usage: " + Environment.GetCommandLineArgs()[0] + " haystack needle");
                }
                else
                {
                    KMPSearch search = new KMPSearch(args[0], args[1]);
                    int[] matches = search.MatchAll();
                    foreach (int i in matches)
                        Console.WriteLine("Match found at position " + i+1);
                }
            }
    
        }
    }
    
        6
  •  0
  •   GorvGoyl    10 年前

    试试这个,它会返回一个文本数组。例如:“一行”文本“记事本”:

    string textToSearch = "\"a line of\" text \" notepad\"";
    
    MatchCollection allPhrases = Regex.Matches(textToSearch, "(?<=\").*?(?=\")");
    
    var RegArray = allPhrases.Cast<Match>().ToArray();
    

    输出:“一行”,“文本”,“记事本”