正则表达式可以实现吗?

时间:2010-02-09 21:49:53

标签: c# regex tokenize

我正在尝试将字符串拆分为标记(通过正则表达式) 通过以下方式:

示例#1
输入字符串:'hello'
第一个令牌:'
第二个令牌:hello
第三个标记:'

示例#2
输入字符串:'hello world'
第一个令牌:'
第二个令牌:hello world
第三个标记:'

示例#3
输入字符串:hello world
第一个令牌:hello
第二个令牌:world

即,如果字符串不是单引号,则只拆分字符串,单引号应该在它们自己的标记中。

这是我到目前为止所做的:

string pattern = @"'|\s";
Regex RE = new Regex(pattern);
string[] tokens = RE.Split("'hello world'");

这适用于例如#1和示例#3,但它不适用于示例#2。 我想知道理论上是否有办法用正则表达式实现我想要的东西

8 个答案:

答案 0 :(得分:5)

你可以构建一个简单的词法分析器,它将涉及逐个使用每个标记。因此,您将拥有正则表达式列表,并尝试在每个点匹配其中一个。如果您的输入超出了非常简单的范围,那么这是最简单,最干净的方法。

答案 1 :(得分:3)

使用令牌解析器拆分为令牌。使用正则表达式查找字符串模式

答案 2 :(得分:2)

'[^']+'将匹配单引号内的文字。如果您希望将其分组,(')([^']+)(')。如果未找到匹配项,则只需使用常规字符串拆分。我认为尝试用一个正则表达式完成整个事情是没有意义的。

编辑:从您对该问题的评论中可以看出,您实际上希望将其应用于更大的文本块,而不仅仅是您指定的简单输入。如果是这种情况,那么我认为正则表达式不是你的答案。

答案 3 :(得分:1)

您可以先对引用的字符串进行拆分,然后再进行标记化。

foreach (String s in Regex.Split(input, @"('[^']+')")) {
    // Check first if s is a quote.
    // If so, split out the quotes.
    // If not, do what you intend to do.
}

(注意:您需要模式中的括号以确保Regex.Split也返回这些括号)

答案 4 :(得分:1)

不完全是您要做的事情,但正常表达条件可能有助于您寻找解决方案:

(?<quot>')?(?<words>(?(quot)[^']|\w)+)(?(quot)')

如果找到报价,则匹配直到找到非报价。否则看字词。您的结果位于名为“quot”和“words”的组中。

答案 5 :(得分:1)

虽然可以单独匹配'和文本内部,也可以单独匹配文本,但RegExp不允许无限数量的匹配。或者更好地说,您只能匹配表达式中明确表示的那些对象。所以((\w+)+\b)理论上可以逐个匹配所有单词。外部组将正确匹配整个文本,内部组也将正确匹配单词,但您只能引用最后一个匹配。

无法匹配一组匹配的匹配(奇怪的句子)。唯一可能的方法是匹配字符串,然后将其拆分为单独的单词。

答案 6 :(得分:1)

您在这里使用Split时会遇到困难,但您可以使用MatchCollection查找字符串中的所有匹配项:

string str = "hello world, 'HELLO WORLD': we'll be fine.";
MatchCollection matches = Regex.Matches(str, @"(')([^']+)(')|(\w+)");

正则表达式在单引号之间搜索字符串。如果找不到,则只需一个字 现在它有点棘手 - .net返回Match s的集合。每个匹配都有多个Group s - 第一个组具有整个字符串('hello world'),但其余匹配有子匹配('hello world,{{1} })。此外,您将获得许多空的不成功的组 你仍然可以轻松迭代并获得你的比赛。以下是使用LINQ的示例:

'

var tokens = from match in matches.Cast<Match>() from g in match.Groups.Cast<Group>().Skip(1) where g.Success select g.Value; 现在是字符串的集合:
tokenshelloworld'HELLO WORLD'well,{{ 1}}

答案 7 :(得分:0)

试试这个正则表达式:

([']*)([a-z]+)([']*)

在字符串的开头和结尾找到1个或多个单引号。然后它在a-z集中找到1个或多个字符(如果不将其设置为不区分大小写,则只会找到小写字符)。它将这些分组,以便组1具有',组2(或更多)具有由不是字符a-z的任何东西分割的单词,并且如果它存在则最后一组具有单引号。

相关问题