1

I wrote this Regex to match any string before a .= or = or :=

How I could also add to if on the same line exists the word foo it then did not match anything in that line?

https://regex101.com/r/tJRoDh/213

(?!.*foo)\b(\w+)\s*(\.=|=|:=)

x = foo 
foo x= 
x = foo 
foo text :=
text := x text foo

^ don't match any of these because exist the word foo on the same line
---------------------------------------------

text HELLO:= text text
     ^ match hello
text x = text 
     ^ match x
text .= something else y:= color 
^ match text           ^ match y

I'm using the regex on AutoHotkey to match all strings before .= = and :=

  • Sure, i will, btw your pattern did match this line `foo text :=` it contains foo, should not had caught it –  Oct 17 '20 at 02:45
  • 1
    Does this answer your question? [Regular expression to match a line that doesn't contain a word](https://stackoverflow.com/questions/406230/regular-expression-to-match-a-line-that-doesnt-contain-a-word) – ggorlen Oct 17 '20 at 02:45
  • I'm a beginner in regex I don't know how to combine two regex on one –  Oct 17 '20 at 02:47
  • Match any string before a `.= or = or :=` but if on the same line exist the word foo then on that line doesn't match anything –  Oct 17 '20 at 02:55

2 Answers2

1

The following regex seems sufficient:

^(?:(?!foo).)*\b(\w+)\s*(\.=|=|:=)(?:(?!foo).)*$

This uses the canonical Regular expression to match a line that doesn't contain a word before and after the desired substring pattern, thus rejecting lines with the substring "foo" before or after the target.

ggorlen
  • 44,755
  • 7
  • 76
  • 106
  • on the last line text was not caught, its before an `.=` –  Oct 17 '20 at 03:02
  • I see. Capture groups only store the last result so use `preg_match_all` to extract everything programmatically. See [this](https://stackoverflow.com/questions/37003623/how-to-capture-multiple-repeated-groups). There might be a clever way to do it, but I'd probably apply one regex to filter out `foo` lines, then a second to extract the assignment substrings you're interested in. – ggorlen Oct 17 '20 at 03:05
  • I have read the link you post but I did not understand how to apply it to your regex –  Oct 17 '20 at 03:13
  • How are you actually using this regex in your code? – ggorlen Oct 17 '20 at 03:15
  • im using it on autohotkey to catch all declared variables as they are before .= or = or := `regex = Om)\b(\w+)\s*(\.=|=|:=) Matches := RegExMatchAll(sourceB,regex) for i,v in Matches { z := v.value[1] variables.push(z) }` –  Oct 17 '20 at 03:19
  • Please update your post with that code and context. – ggorlen Oct 17 '20 at 03:20
  • I don't see any code in there. What language is this? It doesn't look like PHP to me--probably Golang or something? I'm not sure how to get multiple matches and reject `foo` in one pattern but maybe someone else knows. Until then, I'd just apply two regexes as suggested above. Once you have a matching line it's pretty easy to get all matches from a line with your original regex `/\b(\w+)\s*(\.=|=|:=)/m`. I can offer an example if you can specify the lang you're using with some basic boilerplate. – ggorlen Oct 17 '20 at 03:40
1

AutoHotKey refers to the pcre manual at the regex quick reference

In that case, to get the multiple matches, you could make use of the \G anchor which asserts the position at the end of the previous match of at the start of the string for the first match.

\G(?!.*\bfoo\b)[^.:=\r\n]*(?:[.:](?!=)[^.:=\r\n]*)*\b(\w+)\h*([.:]?=)

Explanation

  • \G Assert the position at the end of the previous match or in this case at the start of the string
  • (?!.*\bfoo\b) Negative lookahead, assert that the string does not contain foo
  • [^.:=\r\n]* Match 0+ times any char except . : = or a newline
  • (?:[.:](?!=)[^.:=\r\n]*)* If it does encounter a . or : only match it when it is not directly followed by = and repeat this 0+ times in case this happens multiple times
  • \b(\w+) Word boundary, capture 1+ word chars in group 1
  • \h*([.:]?=) Match 0+ horizontal whitespace chars and capture in group 2 either .= := or =

Regex demo

The fourth bird
  • 154,723
  • 16
  • 55
  • 70