我正在尝试创建一个C#/ WPF Parser。我对正则表达式有一个很好的全面理解,因为这不是我的第一个解析器(可能不是我的最后一个)
然而,现在我有一种非常奇怪的行为。这是我要解析的内容(注意:实际数据已删除,我只是按照与我相同的结构制作了一个字符串):
aaaaa bbbbb 50 c blabla
我的应用程序会收到我想要分割和识别的行。由于某种原因,空格的数量是可变的(一个在aaaa和bbbb之间,两个在bbbb和50之间......)。 (注意人们告诉我之前:我不会使用string.Split()。因为我有很多不同的线条结构,我应该总是得到相同的数据。只是拆分它会让我无法识别每一个部分意味着)
我目前的测试正则表达式有点简单:
(\S*)[\s*](\S*)[\s*](\S*)[\s*](p|c)(.*)
现在,发生了什么。当bbbbb和50之间只有一个空格时,正则表达式正确解析(注意:我使用http://www.myregextester.com/index.php来测试我的正则表达式)
$matches Array:
(
[0] => Array
(
[0] => aaaaa bbbbb 50 c blabla
)
[1] => Array
(
[0] => aaaaa
)
[2] => Array
(
[0] => bbbbb
)
[3] => Array
(
[0] => 50
)
[4] => Array
(
[0] => c
)
[5] => Array
(
[0] => blabla
)
)
如果bbbb和50之间有两个空格,则会发生以下情况:
$matches Array:
(
[0] => Array
(
[0] => bbbbb 50 c blabla
)
[1] => Array
(
[0] => bbbbb
)
[2] => Array
(
[0] =>
)
[3] => Array
(
[0] => 50
)
[4] => Array
(
[0] => c
)
[5] => Array
(
[0] => blabla
)
)
现在我知道我可以轻松地删除线上不需要的空格(这是我目前所做的)。我无论如何都渴望了解我在那里错过了什么:当我添加一个额外的空间时,为什么会发生这种情况,应该用我添加的[\ s *]中的一个来识别?
谢谢!
答案 0 :(得分:5)
[\s*]
没有做你期望的事。方括号表示一个字符组,这意味着它将匹配一个\s
(空格)或文字* 的字符。
只需删除这些括号即可获得预期的行为:匹配\s
(空格)0次或更多次:
(\S*)\s*(\S*)\s*(\S*)\s*(p|c)(.*)
编辑:Jesse的评论也很有价值:除非某些组真的是可选的,否则您可能希望使用+
而不是*
量词。
答案 1 :(得分:3)
每当我看到正则表达式中的星星时,我都会畏缩。明星匹配零或更多,真的可以绊倒你!将*
的所有实例替换为+
,然后重试。当然,除非其中一些分组确实是可选的。
编辑:其他答案非常正确地指出您使用的是角色组,但我的观点仍然存在:注意*
!
答案 2 :(得分:2)
答案 3 :(得分:-2)
[\ s *]有不同的含义,因为它在括号内[\ s] +表示你想要的行为或[\ s] {1,}这个表达式将匹配空格字符1次或更多次。你还需要记住,根据您正在使用的功能,您可能需要启用'g'标志,这是全局标志,以使您的正则表达式匹配您要解析的模式的所有出现,否则它只能解析第一个比赛。括号否定大多数字符类并将大多数修饰符转换为文字除了少数例外,访问MDN https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions检查您对正则表达式在括号内的行为方式或正则表达式上的PHP API http://php.net/manual/en/reference.pcre.pattern.syntax.php的了解