Adeel Asghar
Adeel Asghar

Reputation: 359

Regex to check the start of String exactly once

I have a string in which I want to match using Regex that either of B1 and B2 occur only once and at start of every new line. Below is the sample and what I tried:

public static String testStr = "A1ABC            10.101.0     testString \r\n"+
                               "B100000100111 B18388831993     I am here\r\n";


public static void main(String args[]) {
    String regex = "^(B1{1}|B2{1}).*$";

    boolean isTrue = testStr.matches(regex);
    if (isTrue) {
        System.out.println("TRUE returns ......... ");
    } else {
        System.out.println("FALSE returns ......... ");
    }
}

In above case it should return TRUE but if I changed my input to:

public static String testStr = "A1ABC            10.101.0     testString \r\n"+
                               "B100000100111 B18388831993     I am here\r\n"+
                               "B2HELLLOWORLD";

But in the the above case it should return FALSE as both B1 and B2 are present. I want to check either of B1 and B2 occur only single time at start of line not in between.

I also use the regex:

          .*\\r?\\n$^B1{1}.*\\r\\n$ | ^B2{1}.*$

Can any one tell me the solution using regex?

Upvotes: 1

Views: 983

Answers (3)

alpha bravo
alpha bravo

Reputation: 7948

for exactly once non-matching use this Pattern it will match 0 and 2 or more occurrences of B1/B2 at beginning of lines (?s)^((?=((^|.*\r?\n)(B1|B2)){2})|^(?!(^|.*\r?\n)(B1|B2))).

  • ^( beginning
  • (?=((^|.*\r?\n)(B1|B2)){2}) lookahead for B1/B2 "2 occurrences"
  • | or
  • ^(?!(^|.*\r?\n)(B1|B2)) negative lookahead for B1/B2 "0 occurrence"
  • ). grap something to return 1 or 0

Upvotes: 0

DavidRR
DavidRR

Reputation: 19397

This regex detects your unwanted situation. Note the use of two flags: m (multiline) and s (single line - dot matches newline characters):

(?ms)^(?:B1|B2).*?^(?:B1|B2)

The presence of ?: suppresses backreferences from being created. (You don't need the backreferences; you only want to know whether you have data that violates your constraint.)

Upvotes: -1

OGHaza
OGHaza

Reputation: 4795

It is easier to test for the opposite, return TRUE if B1/B2 are present twice, then treat the results as the opposite:

(?sm).*^(B1|B2).*?^(B1|B2).*

Using multiline flag (?m) - RegExr

If you do want TRUE to indicate B1/B2 does NOT appear twice, a little messing around has led me to this:

^(?sm)(?!(.*?^(B1|B2)){2}).*

RegExr - Change a line to another B1/B2 and you'll see it stops matching.

But I'm sure that 2nd regex is much less efficient than just flipping the return value of the first one.

Upvotes: 4

Related Questions