Asked  7 Months ago    Answers:  5   Viewed   25 times

I am trying to match a multi line text using java. When I use the Pattern class with the Pattern.MULTILINE modifier, I am able to match, but I am not able to do so with (?m).

The same pattern with (?m) and using String.matches does not seem to work.

I am sure I am missing something, but no idea what. Am not very good at regular expressions.

This is what I tried

String test = "User Comments: This is t ata n test nn message n";

String pattern1 = "User Comments: (\W)*(\S)*";
Pattern p = Pattern.compile(pattern1, Pattern.MULTILINE);
System.out.println(p.matcher(test).find());  //true

String pattern2 = "(?m)User Comments: (\W)*(\S)*";
System.out.println(test.matches(pattern2));  //false - why?

 Answers

60

First, you're using the modifiers under an incorrect assumption.

Pattern.MULTILINE or (?m) tells Java to accept the anchors ^ and $ to match at the start and end of each line (otherwise they only match at the start/end of the entire string).

Pattern.DOTALL or (?s) tells Java to allow the dot to match newline characters, too.

Second, in your case, the regex fails because you're using the matches() method which expects the regex to match the entire string - which of course doesn't work since there are some characters left after (\W)*(\S)* have matched.

So if you're simply looking for a string that starts with User Comments:, use the regex

^s*User Comments:s*(.*)

with the Pattern.DOTALL option:

Pattern regex = Pattern.compile("^\s*User Comments:\s+(.*)", Pattern.DOTALL);
Matcher regexMatcher = regex.matcher(subjectString);
if (regexMatcher.find()) {
    ResultString = regexMatcher.group(1);
} 

ResultString will then contain the text after User Comments:

Tuesday, June 1, 2021
 
braindamage
answered 7 Months ago
43

Continue calling re.exec(s) in a loop to obtain all the matches:

var re = /s*([^[:]+):"([^"]+)"/g;
var s = '[description:"aoeu" uuid:"123sth"]';
var m;

do {
    m = re.exec(s);
    if (m) {
        console.log(m[1], m[2]);
    }
} while (m);

Try it with this JSFiddle: https://jsfiddle.net/7yS2V/

Tuesday, June 1, 2021
 
barden
answered 7 Months ago
69

The dot must be escaped othwerwise it will match every character and you must set the global modifier:

var symbol = $("div.price > h5 > div.num").text().replace(/[d.]+/g, "");
Tuesday, August 3, 2021
 
JontheNerd
answered 4 Months ago
85

You may use

const reg = '(https?://)?([\da-z.-]+)\.([a-z.]{2,6})[/\w .-]*/?';

The ^ (at the start) and $ (at the end) will be added by Angular2 automatically (note that you are in charge of properly grouping the pattern in that case, though in this case it is not required).

The most important part here is that you need to double the escaping backslash in the string literal to define a literal backslash that escapes special regex metacharacters.

Also, you do not need to escape / in a regex constructor notation.

Also, you have ([/w .-]*)* that is a very poor pattern: it is the same as [/\w .-]*, so remove the quantified grouping here.

Wednesday, August 25, 2021
 
DilbertDave
answered 4 Months ago
20

You can use optional matches in your regex to cover all 3 cases:

(d+(?:,d+)?) x (d+(?:,d+)?)(?: x (d+(?:,d+)?))?

RegEx Demo

This will give length in 1st capturing group, width in 2nd capturing group and height in 3rd.

Each group is using this sub-expression:

(d+(?:,d+)?)

Which is 1 or more digits optionally followed by a comma and 1+ digits for decimal part.

Also, note that height part is an optional match as we're using (?: x (d+(?:,d+)?))? to make that part optional.

Tuesday, October 19, 2021
 
Michael
answered 2 Months ago
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :  
Share