-2

It's perhaps quite simple, but I can't figure it out:

I have a random number (can be 1,2,3 or 4 digits) It's repeating on a second line:

2131
2131

How can I remove the first number?

EDIT: Sorry I didn't explained it better. These lines are in a plain text file. I'm using BBEdit as my editor. And the actual file looks like this (only then app. 10.000 lines):

336
336
rinde
337
337
diving
338
338
graffiti
339
339
forest
340
340
mountain

If possible the result should look like this:

336 - rinde
337 - diving
338 - graffiti
339 - forest
340 - mountain
Alan Moore
  • 68,531
  • 11
  • 88
  • 149
  • repeated on 2nd line or 2nd column? in your example it's 2nd column. use Code tag pls. – Kent Sep 28 '11 at 21:02
  • 3
    What language? Are all of these in the same string? Why do you have to use a regex? – CanSpice Sep 28 '11 at 21:04
  • @CanSpice +1 which tool/language is available for you? are those numbers in a file? – Kent Sep 28 '11 at 21:06
  • @Kent: According to the edit, this is being done with BBEdit's search-n-replace, which seems to be posered by the the PCRE library. I've retagged accordingly. – Alan Moore Sep 29 '11 at 04:17

5 Answers5

3

Search:

^(\d{1,4})\n(?:\1\n)+([a-z]+$)

Replace:

\1 - \2

I don't have access to BBEdit, but apparently you have to check the "Grep" option to enable regex search-n-replace. (I don't know why they call it that, since it seems to be powered by the PCRE library, which is much more powerful than grep.)

Alan Moore
  • 68,531
  • 11
  • 88
  • 149
  • 1
    +1, some info for completion: PCRE does not have a substitution function (this might come out in the upcoming pcre2 API) so that has to be implemented in each tool or language; BBEdit uses a very old version of PCRE from early 2003. – zx81 Aug 16 '14 at 22:49
2

since you didn't mention any programming language, tools. I assume those numbers are in a file. each per line, and any repeated numbers are in neighbour lines. uniq command can solve your problem:

kent$  echo "1234
dquote> 1234
dquote> 431
dquote> 431
dquote> 222
dquote> 222
dquote> 234"|uniq

1234
431
222
234
Kent
  • 173,042
  • 30
  • 210
  • 270
  • If they're not in neighbour lines, you could pipe it through `sort` before `uniq`, but then you lose ordering. Whether or not ordering is important is probably something that won't be answered by the person asking the question, however... – CanSpice Sep 28 '11 at 21:31
  • @CanSpice OP mentioned `It's repeating on a second line` also from the example, I thought they are in neighbour lines. If not, there are other solutions, e.g. awk/sed can handle it well, even if the ordering need to be kept. – Kent Sep 28 '11 at 21:37
2

Another way find: /^(\d{1,4})\n(?=\1$)/ replace: ""
modifiers mg (multi-line and global)

$str =
'1234
1234
431
431
222
222
222
234
234';

$str =~ s/^(\d{1,4})\n(?=\1$)//mg;
print $str;

Output:
1234
431
222
234

Added On the revised sample, you could do something like this:

Find: /(?=^(\d{1,4}))(?:\1\n)+\s*([^\n\d]*$)/
Replace: $1 - $2
Mods: /mg (multi-line, global)

Test:

$str =
'
336
336
rinde
337
337
337
diving
338
338
graffiti
339
337
339
forest
340
340
mountain
';

$str =~ s/(?=^(\d{1,4}))(?:\1\n)+\s*([^\n\d]*$)/$1 - $2/mg;

print $str;

Output:
336 - rinde
337 - diving
338 - graffiti
339
337
339 - forest
340 - mountain

Added2 - I was more impressed with the OP's later desired output format than the original question. It has many elements to it so, unable to control myself, generated a way too complicated regex.

Search: /^(\d{1,4})\n+(?:\1\n+)*\s*(?:((?:(?:\w|[^\S\n])*[a-zA-Z](?:\w|[^\S\n])*))\s*(?:\n|$)|)/
Replace: $1 - $2\n
Modifiers: mg (multi-line, global)

Expanded-

# Find:
s{ # Find a single unique digit pattern on a line (group 1)

   ^(\d{1,4})\n+   # Grp 1, capture a digit sequence

   (?:\1\n+)*      # Optionally consume the sequence many times,
   \s*             # and whitespaces (cleanup)

   # Get the next word (group 2)
   (?:
     # Either find a valid word
       (                      # Grp2 
          (?:
             (?:\w|[^\S\n])*     # Optional \w or non-newline whitespaces
             [a-zA-Z]            # with at least one alpha character
             (?:\w|[^\S\n])*
          )
       )
       \s*                    # Consume whitespaces (cleanup),
       (?:\n|$)               # a newline
                              # or, end of string
     |
     # OR, dont find anything (clears group 2)
   )
 }

# Replace (rewrite the new block)
 {$1 - $2\n}xmg;  # modifiers expanded, multi-line, global
0

find:

((\d{1,4})\r(\D{1,10}))|(\d{1,6})

replace:

\2 - \3

You should be able to clean it up from there quite easily!

-2

Detecting such a pattern is not possible using regexp.

You can split the string by the "\n" and then compare.

robermorales
  • 2,982
  • 2
  • 23
  • 36
  • 1
    I expect the regexp from the downvoters. – robermorales Sep 28 '11 at 21:46
  • 2
    See my answer or CanSpice's for suitable regexes--and that's for the revised question, which is more complex than the original. Why would you think it's not possible? – Alan Moore Sep 29 '11 at 05:00
  • From Wikipedia "Many features found in modern regular expression libraries provide an expressive power that far exceeds the regular languages. For example, many implementations allow grouping subexpressions with parentheses and recalling the value they match in the same expression (backreferences). This means that a pattern can match strings of repeated words like "papa" or "WikiWiki", called squares in formal language theory. The pattern for these strings is `(.*)\1`." – robermorales Sep 29 '11 at 07:11
  • I just understood that a "regular language" should be used. Some languages can have more powerful expressions, but they are not regular. In other words, I said that the problem cannot be solved with a type-3 chomsky grammar. http://en.wikipedia.org/wiki/Chomsky_hierarchy – robermorales Sep 29 '11 at 07:15
  • 2
    I suspected as much: the split personality of regular expressions strikes again! Unless they indicate otherwise, when someone asks about regexes here at SO, you should assume they're talking about the blue-collar *regexes*, not ivory-tower *regular expressions*. :P – Alan Moore Sep 29 '11 at 07:58