# Regex Black Magic... how to stop matching if char?

**URL:** <https://www.ruby-forum.com/t/regex-black-magic-how-to-stop-matching-if-char/90643>\
**Category:** Ruby\
**Created:** [March 30, 2007, 5:34pm UTC](https://www.ruby-forum.com/t/regex-black-magic-how-to-stop-matching-if-char/90643 "2007-03-30T17:34:02Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![jon](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/3bc359/32.png) [@jon](https://www.ruby-forum.com/u/jon)\
**Post date:** [March 30, 2007, 5:34pm UTC](https://www.ruby-forum.com/t/regex-black-magic-how-to-stop-matching-if-char/90643/1 "2007-03-30T17:34:02Z")

</div>

I’m trying to translate a strange derivative of xml into valid xml. Here  
is an example line:

\<SUBEVENTSTATUS  
1:2\>gofaststoppednameval\</SUBEVENTSTATUS  
1:1\>\<SUBEVENTSTATUS 2:2\>\<…and on

REXML pukes on the \<SUBEVENTSTATUS 1:2\> tag… which it should. There  
should be some kind of attribute declaration instead. I want to  
translate it to something like this:

I’m trying to make a regex to detect the funny tags. Here is what I have  
so far:

xml\_fix=/\<(\S+)\s+(\d+):(\d+)\>/

This is great, but it will match this:

\<code\_set\_list 1:2\>

instead of just this:

\<code\_set\_list 1:2\>

…because there is no gauranteed whitespace between tags. Basically, I  
need to stop matching if a “\>” is found. I’ve never had to deal with  
anything quite like this in my regex experience. Any help or thoughts of  
a better way to do things is much appreciated!

---

<div class="post-metadata">

**Author:** ![jon](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/3bc359/32.png) [@jon](https://www.ruby-forum.com/u/jon)\
**Post date:** [March 30, 2007, 5:40pm UTC](https://www.ruby-forum.com/t/regex-black-magic-how-to-stop-matching-if-char/90643/2 "2007-03-30T17:40:56Z")

</div>

On 30.03.2007 17:34, Jon wrote:

> \<code\_set\_list 1:2\>
> 
> …because there is no gauranteed whitespace between tags. Basically, I  
> need to stop matching if a “\>” is found. I’ve never had to deal with  
> anything quite like this in my regex experience. Any help or thoughts of  
> a better way to do things is much appreciated!

I can think of several solutions:

/\<([^\>\s]+)\s+(\d+):(\d+)\>/

Or even a two phased approach

/\<[^\>]+\>/

and then with the match  
/(\d+):(\d+)\>\z/

HTH

robert

---

<div class="post-metadata">

**Author:** ![jon](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/3bc359/32.png) [@jon](https://www.ruby-forum.com/u/jon)\
**Post date:** [March 30, 2007, 5:43pm UTC](https://www.ruby-forum.com/t/regex-black-magic-how-to-stop-matching-if-char/90643/3 "2007-03-30T17:43:56Z")

</div>

Robert K. wrote:

> On 30.03.2007 17:34, Jon wrote:
> 
> > \<code\_set\_list 1:2\>
> > 
> > …because there is no gauranteed whitespace between tags. Basically, I  
> > need to stop matching if a “\>” is found. I’ve never had to deal with  
> > anything quite like this in my regex experience. Any help or thoughts of  
> > a better way to do things is much appreciated!
> 
> I can think of several solutions:
> 
> /\<([^\>\s]+)\s+(\d+):(\d+)\>/
> 
> Or even a two phased approach
> 
> /\<[^\>]+\>/
> 
> and then with the match  
> /(\d+):(\d+)\>\z/
> 
> HTH
> 
> robert

awesome, and thank you! but for my benefit, could you explain why that  
works? I thought ^ was line start?

---

<div class="post-metadata">

**Author:** ![jon](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/3bc359/32.png) [@jon](https://www.ruby-forum.com/u/jon)\
**Post date:** [March 30, 2007, 5:46pm UTC](https://www.ruby-forum.com/t/regex-black-magic-how-to-stop-matching-if-char/90643/4 "2007-03-30T17:46:58Z")

</div>

Le 30 mars à 17:34, Jon a écrit :

> …because there is no gauranteed whitespace between tags. Basically, I  
> need to stop matching if a “\>” is found. I’ve never had to deal with  
> anything quite like this in my regex experience. Any help or thoughts of  
> a better way to do things is much appreciated!

I’d simply use /\<[^\>]+\s+(\d+):(\d+)\>/ (untested, but you get my  
drift)…

Fred

---

<div class="post-metadata">

**Author:** ![jon](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/3bc359/32.png) [@jon](https://www.ruby-forum.com/u/jon)\
**Post date:** [March 30, 2007, 6:18pm UTC](https://www.ruby-forum.com/t/regex-black-magic-how-to-stop-matching-if-char/90643/5 "2007-03-30T18:18:16Z")

</div>

On Mar 30, 2007, at 11:43 AM, Jon Fi wrote:

> > > thoughts of  
> > > and then with the match  
> > > /(\d+):(\d+)\>\z/
> > 
> > HTH
> > 
> > robert
> 
> awesome, and thank you! but for my benefit, could you explain why that  
> works? I thought ^ was line start?

Within a character set it inverts the selection so [^\>] matches any  
character that’s NOT a ‘\>’

My solution is: .gsub(/\<([^\>]\*?\b\s+)(\d+):(\d+)\>/, ‘\<\1no=“\2”  
of=“\3”\>’)

-Rob

Rob B. [http://agileconsultingllc.com](http://agileconsultingllc.com)  
removed\_email\_address@domain.invalid

---

<div class="post-metadata">

**Author:** ![jon](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/3bc359/32.png) [@jon](https://www.ruby-forum.com/u/jon)\
**Post date:** [March 31, 2007, 10:33am UTC](https://www.ruby-forum.com/t/regex-black-magic-how-to-stop-matching-if-char/90643/6 "2007-03-31T10:33:52Z")

</div>

On Sat, Mar 31, 2007 at 12:34:25AM +0900, Jon wrote:

> xml\_fix=/\<(\S+)\s+(\d+):(\d+)\>/
> 
> This is great, but it will match this:
> 
> \<code\_set\_list 1:2\>
> 
> instead of just this:
> 
> \<code\_set\_list 1:2\>

Try (\w+) instead of (\S+)
