2013-05-21 31 views
0

这里是东西:NSRegularExpression发现图案可选部分

我有一个文件存储一些DATAS,以下模式:

item1:value1 item2:value2 item3:value3 // \n 
item1:value1 item2:value2 
item1:value1 item2:value2 
// and so on... 

// item3:value3 IS OPTIONAL 

然后我的文件DATAS存储在NSString,以处理它们。

我想匹配value2,但事情是item3:value3的存在是在每行中可选的。

所以我试图使用?正则表达式运算符,但我不确定使用它的方式。

所以通常我试图匹配以下模式(不工作,OFC):

@"item1:.* item2:(.*) (item3:.*)?\n" 

更好地解释,我想重新组合2个条件1:

@"item1:.* item2:(.*) item3:.*\n" // Case 1 : item3:.* present in the line 
@"item1:.* item2:(.*)\n"   // Case 2 : item3 not present 

请注意,我已经创建了一个个人化的函数,返回NSMutableArray中的所有匹配项。

我希望这是非常明显的:/

感谢您的帮助和想法。

回答

1

好吧,它看起来像那个正则表达式中有几个错误:我现在会穿过它们。

首先,您试图将行的结尾与“\ n”匹配。如果你的字符串以新行结束,这将工作正常,但不会匹配最后一行。为了解决这个问题,用“$”符号,并确保通过NSRegularExpressionAnchorsMatchLines作为options:参数当实例正则表达式,如:

NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"item1:.* item2:(.*?)(?: item3:.*)?$" 
                options:NSRegularExpressionAnchorsMatchLines 
                error:nil]; 

$符号被称为锚,默认情况下匹配字符串的结尾。它的对面是^锚点,它匹配字符串的开头。但是,如果您通过NSRegularExpressionAnchorsMatchLines选项,则这些锚会更改行为以匹配任何字符串行的开始和结束。其次,你使用飞机parethensis,(),将“item3:”部分分组,但是你不想因为匹配(“捕获”)而将这个组合出来。如果您不想“捕捉”组中的文本,请编写像(?:...)这样的组。严格地说,使用平面括号可以工作(并且在你的例子中),但意味着正则表达式引擎必须做更多的工作,因为它需要跟踪捕获组内的内容,以便在方法返回时可以访问它(在你的情况下与rangeAtIndex:2)。

第三,如果item2的数据以空格结尾,或者行中有一个空格,那么您在正则表达式中放置了一个空格(就在item3组的左括号之前),这样您的正则表达式只会匹配一行item3条目。这就是它看起来好像?在你的正则表达式中不起作用,并且将自己解决你的主要问题。该空间需要位于问号后面的组内,否则只有当空间实际存在时,您的正则表达式才会匹配!

最后:*运营商默认为贪婪,这意味着它将尽可能匹配。这会使得正则表达式的(.*)部分消耗掉所有文本直到行尾,并且正则表达式仍然匹配,因为(item3:.*)?部分是可选的。后*(即.*?)放置?改变了*作品,使其,使其尽可能少的文字尽可能匹配,这意味着,如果可能的话,正则表达式会喜欢的项目3部分匹配方式正则表达式的item2:(.*)部分正则表达式的(item3:.*)?部分的一行。

所以,你的正则表达式将如下所示:

@"item1:.* item2:(.*?)(?: item3:.*)?$" 
+0

我不明白,但它无法正常工作:/ – Lucien

+0

对不起,我错位了一个空间。试试看。我是否理解你的问题是你只想要返回item2的值,而没有别的,但是你的尝试返回的太多了? –

+0

我想在案件中匹配item2: 1. item3存在 2. item3不存在 因为item3是可选的,所以它可以在这里或不在! :) – Lucien

0

所以,如果你有可靠一致的模式在你的文字,你可以分析模式来构建你的正则表达式和Objective-C的逻辑。

首先确定可以将感兴趣的元素可靠分离的子字符串。 从粘贴的内容中假设 首先,您可以用新行分隔符分隔每个项目。 制作一系列线条。如果每个系列的编号项目都以某种方式相关,这很有用。

接下来,看起来与你贴什么,你可能有多种方式来识别每一个你感兴趣的线的部分。

同样,你真的需要简单地有什么可能的一些想法在你的弦乐中,而不是在它们中。

当且仅当项目本身不包含空白时,才可以使用空格来进一步标识单独的项目。 如果您只能验证项目是这样定义的,那么您有一些工作: 定义: 一个项目是紧跟在具有以下模式的字符串后面的字符串: 行或单个空格的后面跟着“项目“,后面跟着一个数字1,2或3,后面跟着一个”:“

值字符串的末尾由行尾或分隔符开始另一个项目分隔。

从这里你应该能够用正则表达式替换模式的定义。

你将有一个更简单的时间,如果你打破这个到使用的编程语言逻辑和条件多步骤,不要试图在一个单一的正则表达式做的一切。

+0

我已经想过了,但我更喜欢尝试使用RegEx和'NSRegularExpression'类,因为我知道这些工具中有很多强大的功能,我还不知道。而且我知道我的方式比使用这些工具直到刀柄更重。 – Lucien