0

事情是这样的:

我有一个文件存储一些数据,遵循模式:

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

// item3:value3 IS OPTIONAL

然后我将文件的数据存储在 a 中NSString,以处理它们。

我想匹配 value2 但问题是item3:value3每行中的 pesence 是可选的。

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

所以通常我会尝试匹配以下模式(不起作用,ofc):

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

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

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

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

我希望这足够清楚:/

感谢您的帮助和想法。

4

2 回答 2

1

好的,看起来该正则表达式中有几个错误:我现在将运行它们。

首先,您尝试将行尾与“\n”匹配。如果您的字符串以新行结尾,这将正常工作,但否则将不匹配最后一行。要解决此问题,请使用“$”符号,并确保在实例化正则表达式时NSRegularExpressionAnchorsMatchLines作为参数传递,例如:options:

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

$符号称为锚点,默认情况下匹配字符串的结尾。它的对面是^锚点,它与字符串的开头相匹配。但是,如果您传递该NSRegularExpressionAnchorsMatchLines选项,这些锚点会更改行为以匹配字符串任意行的开头和结尾。

其次,您正在使用 plane parethensis,()对“item3:”部分进行分组,但您不希望由于匹配(“捕获”)而将该组排除在外。如果您不想“捕获”组中的文本,请将组写成(?:...). 严格来说,使用平面括号会起作用(在您的示例中也是如此),但这意味着正则表达式引擎必须做更多的工作,因为它需要跟踪捕获组中的内容,以便您可以在方法返回时访问它(在你的情况下rangeAtIndex:2)。

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

最后:*操作符默认是贪婪的,这意味着它会尽可能多地匹配。这具有使(.*)正则表达式的一部分吃掉所有文本直到行尾的效果,并且正则表达式仍将匹配,因为该(item3:.*)?部分是可选的。在(ie )?之后放置 a会改变工作方式,使其变得惰性,以便匹配尽可能少的文本,这意味着,如果可能,正则表达式将更倾向于将行的 item3 部分与正则表达式覆盖正则表达式的一部分。*.*?*(item3:.*)?item2:(.*)

所以你的正则表达式看起来像:

@"item1:.* item2:(.*?)(?: item3:.*)?$"
于 2013-05-21T09:05:18.640 回答
0

因此,如果您的文本中有可靠一致的模式,您可以分析这些模式以构建您的正则表达式和 Objective-C 逻辑。

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

接下来,从您粘贴的内容来看,您可能有多种方法来识别您感兴趣的每一行的部分。

同样,您确实需要简单地了解您的字符串中可能包含哪些内容以及其中不包含哪些内容。

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

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

由此,您应该能够用正则表达式替换模式的定义。

如果您使用编程语言逻辑和条件将其分解为多个步骤,并且不要尝试在单个正则表达式中完成所有操作,您将拥有更轻松的时间。

于 2013-05-21T09:45:47.937 回答