Replace Every Single Character at the Start of String That Matches a Regex Pattern

Replace every single character at the start of string that matches a regex pattern

You may use

mystring <- c("000450")
gsub("\\G0", "x", mystring, perl=TRUE)
## => [1] "xxx450"

See the regex demo and an R demo

The \\G0 regex matches 0 at the start of the string, and any 0 that only appears after a successful match.

Details

  • \G - an anchor that matches ("asserts") the position at the start of the string or right after a successful match
  • 0 - a 0 char.

Replace all characters before @

You can use

'test@gmail.com'.gsub(/.(?=.*@)/, '*')

See the regex demo and the Ruby demo.

The .(?=.*@) regex matches any one char other than line break chars that is immediately preceded with any zero or more chars other than line break chars and then a @ char.

It is unlikely there can be line break chars in the email addres, but if you ever need to support line breaks, do not forget to add m flag:

/.(?=.*@)/m

Python (Regex: Replacing Every Character After a Single Letter)

You may use

re.sub(r"\b(AVENUE\s+[A-Z]).*", r"\1", text, flags=re.I)

See the regex demo and the Python demo:

import re
strs = ['9201 AVENUE B - GROUND FL REAR', '56-58 AVENUE B STORE #2', '9201 AVENUE B - GROUND FL REAR', '1315 AVENUE C', '431 WEST AVENUE D BASEMENT UNIT', '12334 Avenue Z Store ']
for s in strs:
print(re.sub(r"\b(AVENUE\s+[A-Z]).*", r"\1", s, flags=re.I))
# => [9201 AVENUE B, 56-58 AVENUE B, 9201 AVENUE B, 1315 AVENUE C, 431 WEST AVENUE D, 12334 Avenue Z]

The pattern matches:

  • \b - a word boundary
  • (AVENUE\s+[A-Z]) - Group 1 (the value is referred to with the \1 placeholder from the replacement pattern):

    • AVENUE - a literal string
    • \s+ - 1+ whitespaces
    • [A-Z] - an ASCII letter
  • .* - any 0+ chars other than line break chars as many as possible.

NOTE: the re.I flag will make the [A-Z] case insensitive. To avoid that, use re.sub(r"\b((?i:AVENUE)\s+[A-Z]).*", r"\1", s), see this Python demo.

Replace a single character within a match via Regex

preg_replace('/([0-9])-([0-9])/', '$1.$2', $string);

Should do the trick :)

Edit: some more explanation:

By using ( and ) in a regular expression, you create a group. That group can be used in the replacement. $1 get replaced with the first matched group, $2 gets replaced with the second matched group and so on.

That means that if you would (just for example) change '$1.$2' to '$2.$1', the operation would swap the two numbers.
That isn't useful behavior in your case, but perhaps it helps you understand the principle better.

RegEx to replace entire string with first two values

One option could be using a single capture group and use that in the replacement.

^(\w+(?:-\w+)?(?: +\/)? +\w+(?:-\w+)?).+

The pattern matches:

  • ^ Start of string
  • ( Capture group 1
    • \w+(?:-\w+)?Match 1+ word charss with an optional part to match a - and 1+ word chars
    • (?: +\/)? Optionally match /
    • +\w+(?:-\w+)? Match 1+ word charss with an optional part to match a - and 1+ word chars
  • ) Close group 1
  • .+ Match 1+ times any char (the rest of the line)

If there can be more than 1 hyphen, you can use * instead of ?

Regex demo

Output

AO SMITH
BRA14X18HEBU / P11-042
TWO-HOLE PIPE

A broader match could be matching non word chars in between the words

^(\w+(?:-\w+)*[\W\r\n]+\w+(?:-\w+)*).+

Regex demo

Java: Match with Regex and replace every character

If you have just a single word like that: -

As far as current example is concerned, if you are having just a single word like that, then you can save yourself from regex, by using some String class methods: -

String str = "There exists a word *random*.";

int index1 = str.indexOf("*");
int index2 = str.indexOf("*", index1 + 1);

int length = index2 - index1 - 1; // Get length of `random`

StringBuilder builder = new StringBuilder();

// Append part till start of "random"
builder.append(str.substring(0, index1 + 1));

// Append * of length "random".length()
for (int i = 0; i < length; i++) {
builder.append("*");
}

// Append part after "random"
builder.append(str.substring(index2));

str = builder.toString();

If you can have multiple words like that: -

For that, here's a regex solution (This is where it starts getting a little complex): -

String str = "There exists a word *random*.";
str = str.replaceAll("(?<! ).(?!([^*]*[*][^*]*[*])*[^*]*$)", "*");
System.out.println(str);

The above pattern replaces all the characters that is not followed by string containing even numbers of * till the end, with a *.

Whichever is appropriate for you, you can use.

I'll add an explanation of the above regex: -

(?<! )       // Not preceded by a space - To avoid replacing first `*`
. // Match any character
(?! // Not Followed by (Following pattern matches any string containing even number of stars. Hence negative look-ahead
[^*]* // 0 or more Non-Star character
[*] // A single `star`
[^*]* // 0 or more Non-star character
[*] // A single `star`
)* // 0 or more repetition of the previous pattern.
[^*]*$ // 0 or more non-star character till the end.

Now the above pattern will match only those words, which are inside a pair of stars. Provided you don't have any unbalanced stars.

Replace characters inside a RegEx match

The common approach to matching all occurrences of some pattern inside 2 different delimiters is via using \G anchor based regular expression.

(?i)(?:\G(?!\A)|Catch(?:This|That|Anything)\s*\()[^()"]*\K"

See the regex demo.

Explanation:

  • (?i) - case insensitive modifier
  • (?: - a non-capturing group matching 2 alternatives

    • \G(?!\A) - a place in the string right after the previous successful match (as \G also matches the start of the string, the (?!\A) is necessary to exclude that possibility)
    • | - or
    • Catch(?:This|That|Anything) - Catch followed with either This or That or Anything
    • \s* - 0+ whitespaces
    • \( - a literal ( symbol
  • ) - end of the non-capturing group
  • [^()"]* - any 0+ chars other than (, ) and "
  • \K - a match reset operator
  • " - a double quote.

Java regex, replace certain characters except if it matches a pattern

You may use the following pattern:

\"(?!key\")(.+?)\"

And replace with $1

Details:

  • \" - Match a double quotation mark character.

  • (?!key\") - Negative Lookahead (not followed by the word "key" and another double quotation mark).

  • (.+?) - Match one or more characters (lazy) and capture them in group 1.

  • \" - Match another double quotation mark character.

  • Substitution: $1 - back reference to whatever was matched in group 1.

Regex demo.

Here's a full example:

String str = "\"person\",\"hobby\",\"key\"";
String pattern = "\"(?!key\")(.+?)\"";
String result = str.replaceAll(pattern, "$1");

System.out.println(result); // person,hobby,"key"

Try it online.



Related Topics



Leave a reply



Submit