Question

I'm trying another find/replace with regex, and I've got some oddball characters that I'm tripping over.


Summary:
Some lines (in this carat separated file) have a specific tag or two in peren's (either "(S)" or "(N)") following the part number, and I need to move it to before the PN.
Note: For the lines with both the (S) and the (N), it will always be in that order: (S)(N)


Subject:

^901A-123^DESC,OF,PROD,AND,STUFF^$28.87^$23.10^--^--^--^--^^
^123B-C45(N)^DESC,OF,PROD,AND,STUFF^$1,224.87^$1,041.10^--^--^--^--^^
^333-11(S)(N)^DESC,OF,PROD,AND,STUFF^$510.67^$459.50^$382.90^2^$357.40^4^^
^333-987M-88(S)^DESC,OF,PROD,AND,STUFF^$608.77^$547.90^$456.50^2^$426.10^4^^


What I've Tried:
I started out trying stuff like ^(.+)\(N\)^ and ^([A-Za-z0-9]+)\(N\)^, but soon started to wonder whether the ^(carat) was complicating things so I tried escaping it.
That didn't seem to make a difference :)
So next I tried changing all the carats to pipes:

|901A-123|DESC,OF,PROD,AND,STUFF|$28.87|$23.10|--|--|--|--||
|123B-C45(N)|DESC,OF,PROD,AND,STUFF|$1,224.87|$1,041.10|--|--|--|--||
|333-11(S)(N)|DESC,OF,PROD,AND,STUFF|$510.67|$459.50|$382.90|2|$357.40|4||
|333-987M-88(S)|DESC,OF,PROD,AND,STUFF|$608.77|$547.90|$456.50|2|$426.10|4||

... and searching with |([A-Za-z0-9]+)\(N\)|, and now I'm getting ... wait for it ..... nothing :)


Goal:
While right now I'd be happy with the small victory of figuring out the Find, the ultimate goal is a Replace with a backreference (of the PN).
The goal is to make the subject look like this:

^901A-123^DESC,OF,PROD,AND,STUFF^$28.87^$23.10^--^--^--^--^^
(N)^123B-C45^DESC,OF,PROD,AND,STUFF^$1,224.87^$1,041.10^--^--^--^--^^
(S)(N)^333-11^DESC,OF,PROD,AND,STUFF^$510.67^$459.50^$382.90^2^$357.40^4^^
(S)^333-987M-88^DESC,OF,PROD,AND,STUFF^$608.77^$547.90^$456.50^2^$426.10^4^^


Any and all pointers/suggestions are welcome.

Was it helpful?

Solution 3

Unfortunately you are fighting with special characters: ^, (), |. You need to escape all of them. So you can use this regex (see it in action):

\^([^\^]+?)(\(S\))?(\(N\))?(\^.*)

and replace with this:

$2$3^$1$4

I assumed that you have (S) and (N) only after first tag. Output looks like this:

^901A-123^DESC,OF,PROD,AND,STUFF^$28.87^$23.10^--^--^--^--^^
(N)^123B-C45^DESC,OF,PROD,AND,STUFF^$1,224.87^$1,041.10^--^--^--^--^^
(S)(N)^333-11^DESC,OF,PROD,AND,STUFF^$510.67^$459.50^$382.90^2^$357.40^4^^
(S)^333-987M-88^DESC,OF,PROD,AND,STUFF^$608.77^$547.90^$456.50^2^$426.10^4^^

Explanation

Regex:

\^               #            match '^' character
([^\^]+?)        # group 1  : match any char other than '^' one or more times, non-greedy
(\(S\))?(\(N\))? # group 2-3: match "(S)" and/or "(N)" or none of them
(\^.*)           # group 4  : match '^' and then everything

Replacement:

$2$3^$1$4        # concatenate group 2, then 3 and 1 and 4 after a '^' character

OTHER TIPS

  • ^ and | both are metacharacters that need to be escaped.
  • Your character class [A-Za-z0-9]+ doesn't include the dash.

So, try this: Search for

(\^[A-Za-z0-9-]+)((?:\(S\))?(?:\(N\))?)

and replace with

\2\1

Search for:

^(.*?)(\((S\)\(N|S|N)\))(.*?)$

Replace with:

$2$1$4

Since I anchored the pattern with ^ and $, you have to apply this regex on each line separately or to use the multiline flag.

Here is a working demo.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top