正则表达式:使用前缀替换匹配组中的所有大写字母

时间:2018-03-29 13:31:33

标签: regex perl

假设数据库记录的SQL INSERT行:

.... ,'DateOfBirth' , N'DateOfBirth')

如何在单个Perl REGEX表达式中将其替换为以下内容?

.... ,'DateOfBirth' , N'Date Of Birth')

目的是保持第一列不变,同时向第二个Description列添加空格。

以下是我的发现:

Pattern: (, N'.+)([a-z])([A-Z])(.+)
Returns: ,'DateOfBirth' , N'DateOf Birth')  -- "DateOf" missed by the pattern.

Pattern: "[A-Z]" to replacement " \1" -- Gets the job done, but all Uppercase occurence impacted.
Returns: ,'Date Of Birth' , N'Date Of Birth')

4 个答案:

答案 0 :(得分:2)

您可以使用此正则表达式进行搜索:

/(?:N'|(?!\A)\G)[A-Z][a-z]*/g

并将其替换为:

"$0 "

\G在上一场比赛结束时或第一场比赛的字符串开头处断言位置。在这种情况下,我们首先找到N'后跟一个大写字母后跟0或更多小写字母。然后在那个地方插入一个空格。然后使用\G我们会在上一场比赛结束时找到下一场比赛。

(?!\A)是负面的预测,以确保我们不匹配行的开头。

RegEx Demo

答案 1 :(得分:1)

Perl 提高可读性/可维护性的方法:

#!/usr/bin/env perl

use strict; use warnings;

sub f {
    $_ = shift;
    return join " ", split /([A-Z]+[a-z]+)/;
}

while (<>) {
    s|(?<=N')([^']+)|f($1)|e;
    print;
}

或者在shell中:

$ echo ".... ,'DateOfBirth' , N'DateOfBirth')" | perl -pe '
    BEGIN{
        sub f {
            $_ = shift;
            return join " ", split /([A-Z]+[a-z]+)/;
        }
    }
    s|(?<=N\047)([^\047]+)|f($1)|e
'

输出:

.... ,'DateOfBirth' ,  N'Date  Of  Birth')

注意:

答案 2 :(得分:0)

(?:(?:\sN')?([A-Z][a-z]*)|(?:\1))(\1)*匹配'Date' 'Of''Birth'

答案 3 :(得分:0)

根据UltraEdit查找/替换(Boost C ++ Perl 5.8正则表达式语法)提供的答案设计的工作解决方案:

Find Pattern:   
(N'[A-Z][a-z]+|\G)([a-z]+)([A-Z]+)

Replace Pattern:
\1\2 \3
\1 is (N'[A-Z][a-z]+|\G)
\2 is ([a-z]+)
\3 is ([A-Z]+)

Input:
.... ,'DateOfBirth' , N'DateOfBirth')

Output:
.... ,'DateOfBirth' , N'Date Of Birth')