简体   繁体   中英

Regex : Replace All Uppercase in a Matched Group with a prefix

Assuming an SQL INSERT line for a database record:

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

How can I replace it to become the following, in a single Perl REGEX expression ?

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

The intention is to leave the first column untouched, while adding spaces to the second Description column.

The following are my findings:

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')

You may use this regex for searching:

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

and replace this with:

"$0 "

\\G asserts position at the end of the previous match or the start of the string for the first match. In this case we first find N' followed by an uppercase letter followed by 0 or more lowercase letters. Then insert a space at that place. Then using \\G we find next match from end of previous match.

(?!\\A) is negative lookahead to make sure we don't match start of line.

RegEx Demo

Perl's way for better readability/maintainability :

#!/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;
}

Or in a 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
'

Output :

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

Note :

  • (?<=N') is a look around assertion
  • to do the trick, I run f() function in the substitution, permited by the e modifier

(?:(?:\\sN')?([AZ][az]*)|(?:\\1))(\\1)*匹配'Date' 'Of''Birth'

Working Solution devised from answers provided, for UltraEdit Find/Replace (Boost C++ Perl 5.8 Regex Syntax):

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')

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM