RegEx匹配分隔符之间或开头或结尾的字符串

时间:2014-04-02 18:00:03

标签: regex language-agnostic

我正在处理CSV文件,并希望搜索和替换字符串,只要它与列中的完全匹配即可。例如:

xxx,Apple,Green Apple,xxx,xxx
Apple,xxx,xxx,Apple,xxx
xxx,xxx,Fruit/Apple,xxx,Apple

我想取代Apple'如果它是列中的EXACT值(如果它包含在另一列中的文本中,我不想替换)。我看不出如何使用单个表达式(可能不可能?)。

所需的输出是:

xxx,GRAPE,Green Apple,xxx,xxx
GRAPE,xxx,xxx,GRAPE,xxx
xxx,xxx,Fruit/Apple,xxx,GRAPE

所以我想要的表达式是:匹配输入的开头或逗号,后跟所需的字符串,后跟逗号或输入的结尾。

你不能把^或$放在字符类中,所以我尝试了\ A和\ Z但是没有用。

([\A,])Apple([\Z,])

遗憾的是,这并没有奏效。我可以用一个正则表达式做到这一点吗?这似乎是一个常见的问题。

3 个答案:

答案 0 :(得分:5)

这取决于您的语言,但如果您使用的语言支持外观,那么您可以使用以下内容:

(?<=,|^)Apple(?=,|$)

替换为GRAPE

否则,您将不得不放回逗号:

(^|,)Apple(,|$)

或者

(\A|,)Apple(,|\Z)

并替换为:

\1GRAPE\2

或者

$1GRAPE$2

取决于支持的内容。

以上是原始正则表达式(和替换)字符串。必要时逃脱。

注意:后一种解决方案的缺点是它不能用于以下字符串:

xxx,Apple,Apple,xxx,xxx

自第一个Apple消耗后的逗号。如果遇到这种情况,你必须最多两次调用正则表达式。


哦,我忘了提及,你可以有一些'混合',因为某些语言对于lookbehinds有不同程度的支持(在以下^\A$以下和\Z\1$1是可以互换的,所以我不会让它比现有的更长):

(?:(?<=,)|(?<=^))Apple(?=,|$)

对于那些外观不能宽度可变的人,请替换为GRAPE

(^|,)Apple(?=,|$)

以上是支持前瞻但不支持外观的方法。替换为\1Apple

答案 1 :(得分:2)

这可以按照您的意愿:

  • 找到:(^|,)(?:Apple)(,|$)
  • 替换为:$1GRAPE$2

这适用于regex101,各种风格。

http://regex101.com/r/iP6dZ8

答案 2 :(得分:0)

我想分享我原来的解决方法(在其他答案之前),虽然感觉更像是一个黑客。

在做更简单的事情之前,我只是在字符串前面添加一个逗号:

/,Apple,/,GRAPE,/g

然后切断第一个和最后一个角色。

PHP看起来像:

$line = substr(preg_replace($search, $replace, ','.$line.','), 1, -1);

这仍然存在连续列的问题(例如&#34;,Apple,Apple,&#34;)。