正则表达式:用不一致的模式分隔字符串 (Oracle) (POSIX ERE)
Regex: Separate a string of characters with a non-consistent pattern (Oracle) (POSIX ERE)
编辑:此问题与不支持 'lookaheads'
的正则表达式 (POSIX ERE) 的 Oracle 实现有关
我需要用逗号分隔一串字符,但是模式不一致,我不确定是否可以用 Regex 来完成。
语料库:1710ABCD.131711ABCD.431711ABCD.41711ABCD.4041711ABCD.25
模式基本上是4个数字,后面跟着4个字符,后面跟着一个点,后面跟着1,2,或者3个数字!为了使上面的字符串清晰,这是用 space 1710ABCD.13 1711ABCD.43 1711ABCD.4 1711ABCD.404 1711ABCD.25
分隔的样子
所以替换操作的输出应该是这样的:
1710ABCD.13,1711ABCD.43,1711ABCD.4,1711ABCD.404,1711ABCD.25
我能够使用此正则表达式匹配模式:
(\d{4}\w{4}\.\d{1,3})
它确实插入了一个逗号,但在点之后的第三个数字之后(错误,应该在第二个数字之后),但我无法在正确的位置和全局范围内做到这一点。
这是一个link到一个fiddle
https://regex101.com/r/qQ2dE4/329
你所需要的只是在正则表达式的末尾进行前瞻,以便贪婪的 \d{1,3}
回溯直到它后面跟着 4 位数字(表示下一个子字符串的开始):
(\d{4}\w{4}\.\d{1,3})(?=\d{4})
^^^^^^^^^
为了扩展@CertainPerformance 的答案,如果您希望能够匹配最后一个标记,您可以使用替代匹配 $
:
(\d{4}\w{4}\.\d{1,3})(?=\d{4}|$)
演示:https://regex101.com/r/qQ2dE4/331
编辑:既然你现在在评论中提到你正在使用 Oracle 的实现,你可以简单地做:
regexp_replace(corpus, '(\d{1,3})(\d{4})', ',')
获得你想要的输出:
1710ABCD.13,1711ABCD.43,1711ABCD.4,1711ABCD.404,1711ABCD.25
为了在第一个匹配项之后继续查找匹配项,您必须使用 g
lobal flag /g
。该模式非常棘手,但如果您反转字符串,它是可行的。
演示
var str = `1710ABCD.131711ABCD.431711ABCD.41711ABCD.4041711ABCD.25`;
// Reverse String
var rts = str.split("").reverse().join("");
// Do a reverse version of RegEx
/*In order to continue searching after the first match,
use the `g`lobal flag*/
var rgx = /(\d{1,3}\.\w{4}\d{4})/g;
// Replace on reversed String with a reversed substitution
var res = rts.replace(rgx, ` ,`);
// Revert the result back to normal direction
var ser = res.split("").reverse().join("");
console.log(ser);
编辑:此问题与不支持 'lookaheads'
的正则表达式 (POSIX ERE) 的 Oracle 实现有关我需要用逗号分隔一串字符,但是模式不一致,我不确定是否可以用 Regex 来完成。
语料库:1710ABCD.131711ABCD.431711ABCD.41711ABCD.4041711ABCD.25
模式基本上是4个数字,后面跟着4个字符,后面跟着一个点,后面跟着1,2,或者3个数字!为了使上面的字符串清晰,这是用 space 1710ABCD.13 1711ABCD.43 1711ABCD.4 1711ABCD.404 1711ABCD.25
所以替换操作的输出应该是这样的:
1710ABCD.13,1711ABCD.43,1711ABCD.4,1711ABCD.404,1711ABCD.25
我能够使用此正则表达式匹配模式:
(\d{4}\w{4}\.\d{1,3})
它确实插入了一个逗号,但在点之后的第三个数字之后(错误,应该在第二个数字之后),但我无法在正确的位置和全局范围内做到这一点。
这是一个link到一个fiddle https://regex101.com/r/qQ2dE4/329
你所需要的只是在正则表达式的末尾进行前瞻,以便贪婪的 \d{1,3}
回溯直到它后面跟着 4 位数字(表示下一个子字符串的开始):
(\d{4}\w{4}\.\d{1,3})(?=\d{4})
^^^^^^^^^
为了扩展@CertainPerformance 的答案,如果您希望能够匹配最后一个标记,您可以使用替代匹配 $
:
(\d{4}\w{4}\.\d{1,3})(?=\d{4}|$)
演示:https://regex101.com/r/qQ2dE4/331
编辑:既然你现在在评论中提到你正在使用 Oracle 的实现,你可以简单地做:
regexp_replace(corpus, '(\d{1,3})(\d{4})', ',')
获得你想要的输出:
1710ABCD.13,1711ABCD.43,1711ABCD.4,1711ABCD.404,1711ABCD.25
为了在第一个匹配项之后继续查找匹配项,您必须使用 g
lobal flag /g
。该模式非常棘手,但如果您反转字符串,它是可行的。
演示
var str = `1710ABCD.131711ABCD.431711ABCD.41711ABCD.4041711ABCD.25`;
// Reverse String
var rts = str.split("").reverse().join("");
// Do a reverse version of RegEx
/*In order to continue searching after the first match,
use the `g`lobal flag*/
var rgx = /(\d{1,3}\.\w{4}\d{4})/g;
// Replace on reversed String with a reversed substitution
var res = rts.replace(rgx, ` ,`);
// Revert the result back to normal direction
var ser = res.split("").reverse().join("");
console.log(ser);