我正在尝试将字符串拆分为标记(通过正则表达式) 通过以下方式:
示例#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。 我想知道理论上是否有办法用正则表达式实现我想要的东西
答案 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;
现在是字符串的集合:
tokens
,hello
,world
,'
,HELLO WORLD
,'
,we
,ll
,{{ 1}}
答案 7 :(得分:0)
试试这个正则表达式:
([']*)([a-z]+)([']*)
在字符串的开头和结尾找到1个或多个单引号。然后它在a-z集中找到1个或多个字符(如果不将其设置为不区分大小写,则只会找到小写字符)。它将这些分组,以便组1具有',组2(或更多)具有由不是字符a-z的任何东西分割的单词,并且如果它存在则最后一组具有单引号。