好的,我有一个多行字符串,我正在尝试对其进行一些清理。

每行可能是也可能不是一大段引用文本的一部分。例子:

This line is not quoted.
This part of the line is not quoted “but this is.”
This one is not quoted either.
“This entire line is quoted”
Not quoted.
“This line is quoted
and so is this one
and so is this one.”
This is not quoted “but this is
and so is this.”

我需要一个正则表达式替换,它将解开硬包装的引号行,即将“ ”替换为空格,但仅在大引号之间。

更换后的外观如下:

This line is not quoted.
This part of the line is not quoted “but this is.”
This one is not quoted either.
“This entire line is quoted”
Not quoted.
“This line is quoted and so is this one and so is this one.”
This is not quoted “but this is and so is this.”

(请注意最后两行是输入文本中的多行。)

约束条件

  • 理想情况下需要一个正则表达式替换调用
  • 使用.NET RegEx 库
  • 报价是 总是 开始/结束大引号,而不是普通的双引号(“),这应该会让这更容易一些。

重要制约因素

这不是直接的 .NET 代码,我正在填充一个“searchfor/replacewith”字符串表,然后通过 RegEx.Replace 调用这些字符串。我无法添加自定义代码,例如匹配评估器、循环捕获的组等。

到目前为止,目前的答案大致如下:

r.Replace("(?<=“)\r\n(?=”)", " ")

显然,我还没有接近。

相同的逻辑可以应用于编程代码中块注释的颜色编码——块注释内的任何内容都不会以与注释外的内容相同的方式处理。(代码有点棘手,因为开始/结束块注释分隔符也可以合法地存在于文字字符串中,这是我不必在这里处理的问题。)

有帮助吗?

解决方案

假设所有弯引号都正确平衡,此正则表达式应该执行您想要的操作:

@"[\r\n]+(?=[^“”]*”)"

[\r\n]+ 将匹配任何类型的一个或多个行分隔符 - Unix ( )、DOS ( ) 或更旧的 Mac ( )。然后,前瞻断言前面有一个闭引号,并且这里和那里之间没有开引号。那么您的替换文本可以是一个简单的空格字符。

其他提示

注意:为了测试我使用的正则表达式 http://gskinner.com/RegExr/ 这非常有用。

我认为您无法编写一个表达式来替换未定义数量的换行符。但是,您可以编写一个表达式来替换一个或多个,然后重复运行它或编写它来处理一个引用部分中的最大换行数。

首先,您需要单行模式,以便表达式匹配整个输入字符串而不是逐行匹配。将其放在表达式的开头以将其打开:

(?s)

然后,您需要一个后视表达式来匹配起始引号:

(?<=“)

并进行前瞻以匹配最终引用:

(?=”)

现在是一个匹配一些文本的表达式,然后是一个换行符,然后是一些文本:

([^”\r]*)\r?([^”\r]*)

请注意,换行符周围的文本位有两个捕获组,因此您可以将该文本包含在替换表达式中。这将匹配引号内只有一个换行符的文本。要将其扩展到两个换行符,只需添加另一个可选的换行符和可选的以下文本:

(?s)(?<=“)([^”\r]*)\r?([^”\r]*)\r?([^”\r]*)(?=”)

您可以扩展它以匹配您认为可能出现的任意数量的换行符。并不完美,但也许已经足够了。或者,如果您可以在文本上重复运行该表达式,则一次只需替换一个表达式。

留下你的表情是这样的:

r.Replace("(?s)(?<=“)([^”\r]*)\r?([^”\r]*)", "$1 $2")

(这不太正确,因为即使第二组不匹配,它也会在文本后添加空格......但这是一个开始)

所以要做的就是找到一个以左引号开头的字符串,后跟一个字符串 不是 包含结束引号或任何 字符,后跟一系列一个或多个 字符,捕获除终端 字符之外的所有内容,并将整个匹配替换为捕获的部分。

——马库斯Q

我认为最简单的方法是将引用的部分与 “(?s:.*?)” 并使用 比赛评估器 删除任何换行符。MatchEvaluator 代码可以简单如下

Replace(@"\s+", " ");

当然,您可以对其进行改进,以仅匹配实际包含换行符的引用部分,并仅替换这些部分中的换行符而不是所有空格,但这可能不值得付出努力。

您无法在您所描述的限制内做您想做的事。

证明:

  • 您的固定替换表将执行固定数量的替换调用(将此称为 n)
  • 每次替换只能消除固定数量的换行符(将此数字称为 m)。

所以

  • 带有 m*n+1 换行符的引用块将无法正确处理。

您要么需要增加您的设置的功能(例如通过允许更复杂的替换、递归替换、无限重复标志或...?)或接受您的引擎无法完成此任务的事实。

——马库斯Q

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top