how can i find alternating 1 and 0 using REGEX

Viewed 346

the question is find all bit sequences which are alternating between 1 and 0, i.e., those that do not have more than 1 or 0 in a row and return it in a list.

what i did so far

  public static List<String> findBits(String text) {
    Pattern pattern = Pattern.compile("([01])(?!\\1)([01])(?:\\1\\2)*\\1?|(?<!\\S)[01](?!\\S)|1.|0.", Pattern.DOTALL);
    Matcher matcher = pattern.matcher(text);
    return matcher.results()
        .map(String::valueOf)
        .collect(Collectors.toList());

it should return

no binary numbers here 3434. -> [] Empty List

Hey friend this is a 1. -> [1]

Those are 1001, 1010, 1011, 1100, 1101 -> [1010]

This is a long value 1010101010 and this one as well 1010101010101011 -> [1010101010]

0 + 0 is a also a 0. -> [0,0,0]

2 Answers

You can use

\b(?!\d*(\d)\1)[10]+\b

See the regex demo.

In Java, declare it with "\\b(?!\\d*(\\d)\\1)[10]+\\b".

Details

  • \b - a word boundary
  • (?!\d*(\d)\1) - no repeated subsequent digits allowed in the current number
  • [10]+ - one or more 1 or 0 chars
  • \b - a word boundary

See a Java demo:

public static Pattern pattern = Pattern.compile("\\b(?!\\d*(\\d)\\1)[10]+\\b");
    
public static List<String> findBits(String text) {
    Matcher matcher = pattern.matcher(text);
    return pattern.matcher(text)
        .results()
        .map(MatchResult::group)
        .collect(Collectors.toList()); //.toArray(String[]::new);
}
        
public static void main (String[] args) throws java.lang.Exception
{
    List<String> r = findBits("no binary numbers here 3434. Hey friend this is a 1. Those are 1001, 1010, 1011, 1100, 1101. This is a long value 1010101010 and this one as well 1010101010101011. 0 + 0 is a also a 0.");
    System.out.println(r);
}

// => [1, 1010, 1010101010, 0, 0, 0]

Another option is to repeat a 1 followed by optional repetitions of 01 and end with an optional zero, or the other way around

\b(?>1(?:01)*0?|0(?:10)*1?)\b

The pattern matches:

  • \b A word boundary to prevent a partial match
  • (?> Atomic group
    • 1(?:01)*0? Match 1 optional repetitions of 01 and optional 0
    • | Or
    • 0(?:10)*1? Match 0 optional repetitions of 10 and optional 1
  • ) Close on capture group
  • \b A word boundary

Regex demo | Java demo

For example

public static List<String> findBits(String text) {
    Pattern pattern = Pattern.compile("\\b(?>1(?:01)*0?|0(?:10)*1?)\\b");
    Matcher matcher = pattern.matcher(text);
    return matcher
        .results().map(MatchResult::group)
        .collect(Collectors.toList());
}

Looping the result:

for (String item : findBits("no binary numbers here 3434. Hey friend this is a 1. Those are 1001, 1010, 1011, 1100, 1101. This is a long value 1010101010 and this one as well 1010101010101011. 0 + 0 is a also a 0."))
    System.out.println(item);

Output

1
1010
1010101010
0
0
0
Related