也许是琐碎的问题,但我有问题。我有以下字符串:
,a1a,1a1,11,,aaa,,,a,84.34,"",ssd
我想通过使用正则表达式来实现以下效果:
"","a1a","1a1",11,"","aaa","","","a",84.34,"","ssd"
所以我希望逗号之间的所有内容都包含引号,除了整数和浮点数。如何使用正则表达式执行此操作?
答案 0 :(得分:2)
(*跳过)(* F)魔术
在demo中,查看底部的替换内容。
preg_replace
这是一项很棒的任务,因为PCRE(PHP使用的正则表达式引擎)具有跳过某些内容的漂亮功能。
你可以通过这个可爱的正则表达式一步完成(参见demo):
((?<=^|,)\d+(?:\.\d+)?(?:(?=,)|$)(*SKIP)(*F)|(?<=^|,)[^,]*(?:(?=,)|$))
<强>解释强>
|
OR |
的左侧使用\d+(?:\.\d+)?
来匹配您不想要的这些浮点数和整数。我们使用lookbehind (?<=^|,)
来确保后面有一个逗号(或字符串的开头),并使用(?:(?=,)|$)
来检查后面的内容是逗号还是字符串的结尾。匹配后,我们故意失败,之后引擎跳到字符串中的下一个位置。 [^,]*
匹配任何非逗号的内容,包括空的sring,我们知道它是正确的内容,因为它与左侧的表达式不匹配。我们再次使用外观来检查我们的位置。'"\1"'
将我们的匹配嵌入双引号中。如何在代码中使用它
$regex = "~((?<=^|,)\d+(?:\.\d+)?(?:(?=,)|$)(*SKIP)(*F)|(?<=^|,)[^,]*(?:(?=,)|$))~";
$replaced = preg_replace($regex,'"\1"',$string);
答案 1 :(得分:0)
这是另一种变体:
$regex = '/(?<![^,])(?!"[^"]*")(?![-+]?[0-9]*\.?[0-9]+\b)[^,]*+(?![^,])/';
$result = preg_replace($regex, '"$0"', $subject);
以更易阅读的形式:
(?<![^,])
(?!
"[^"]*"
|
[-+]?[0-9]*\.?[0-9]+\b
)
[^,]*+
(?![^,])
主要兴趣点是:
负前瞻(?<![^,])
以匹配前导分隔符(或不存在)。如果在此位置之前有字符,则可以将其读作,它不能是非逗号。并不总是可以使用这个习惯用法,但我喜欢它,因为它比较常见的(?<=^|,)
感觉不那么笨拙,并且它不会浪费像(^|,)
成语那样的捕获组。
否定前瞻(?![^,])
同样充当结束锚。
在前瞻中,为防止它匹配已经引用的字段,我假设我不必担心转义引号。这些很容易处理,但首先你需要知道它是否使用反斜杠("a\"b\"c"
)或引号("a""b""c"
)来逃避它们。
防止它匹配数字的负向前瞻使用来自RegexBuddy库的正则表达式,它是几个这样的正则表达式中最松散的。如果您需要更精确的东西,可以使用。