[완료] perl 정규식을 사용하는 치환에 대한 질문

eventia의 이미지

perl 치환에 대한 질문입니다. 단순치환이 아니라 조금 복잡하네요. 사실 정규식도 잘 모르는 형편이라 조언을 구합니다.
치환하고자 하는 문자열은 다음과 같습니다(가정). 음악부호들입니다. 처음 숫자는 음의길이고, 두번째 알파벳은 옥타브로 소문자와 대문자로 나눕니다. 두개면 두옥타브, 세개면 세옥타브입니다. 마지막 #, ##, -, -- 가 붙을 수 있습니다.

4FF##
4F--
8A-
16c
4GG##
4g--
4A-
4c

$str = "4FF##\n4F--\n8A-\n16c\n4GG##\n4g--\n4A-\n4c\n";

문제는 여기서 -- 일 경우 조를 하나 내리려고 합니다. F-- 이면 E로 치환합니다. FF-- 면 EE 로 치환합니다. 마찬가지로 ## 인 경우도 하나의 조를 올립니다. F## 이면 G 로 GG## 이면 AA 로 치환합니다. 이 치환하는 방법을 모르겠네요. 혹시 도움주실 분 계시면 고맙겠습니다.

어찌어찌해서 여기까지는 왔는데, ##, -- 를 하나씩 올리고 내리는 것이 어려워서 막혀있습니다. 펄로 가능한 방법이 있을텐데, 제가 펄을 제대로 배운것이 아니라 방법을 못 찾고 있네요. 조언을 구합니다.

1. 앞의 숫자부분은 바꾸지 않는다.
2. a-gA-G 까지 조가 있고 거기에 각각 -- 가 붙으면 하나씩 밑으로 내려간다. (a 아래는 g 다) a,aa,aaa,aaaa, 그 이상도 가능하다.

a->g, b->a, c->b, d->c,...g->f
A->G, B->A, C->B, D->C,...G->F
aa->gg, bb->aa, cc->bb, dd->cc,...gg->ff
AA->GG, BB->AA, CC->BB, DD->CC,...GG->FF

3. a-gA-G 까지 조가 있고 거기에 각각 ## 가 붙으면 하나씩 위로 올라간다. (g 위는 a 다)

a->b, b->c, c->d, d->e,...g->a
A->B, B->C, C->D, D->E,...G->A
aa->bb, bb->cc, cc->dd, dd->ee,...gg->aa
AA->BB, BB->CC, CC->DD, DD->EE,...GG->AA

4. 마지막 --, ## 은 지운다.

단순치환으론 힘들것 같은데, 어떤 명령을 써야 제가 원하는 치환의 형태가 가능할까요?

raymundo의 이미지

저 $str 에 치환을 거치고 나면 어떤 형태가 되어야 한다는 걸 적어주시면 확인하기 더 좋겠습니다만.

#!perl
use strict;
use warnings;
 
my $str = "4FF##\n4F--\n8A-\n16c\n4GG##\n4g--\n4A-\n4c\n";
print $str;     # 변환 전
print "---------\n";
 
my %up = (
    a => "b",       # a 를 한 음 올리면 b
    b => "c",
    c => "d",
    d => "e",
    e => "f",
    f => "g",
    g => "a",
    A => "B",
    B => "C",
    C => "D",
    D => "E",
    E => "F",
    F => "G",
    G => "A",
);
my %down = reverse %up; # 한 음 내리는 건 %up의 역
 
 
$str =~ s/(([a-gA-G])+)##/$up{$2}   x length($1)/eg;
$str =~ s/(([a-gA-G])+)--/$down{$2} x length($1)/eg;
 
print $str;     # 변환 후

4FF##
4F--
8A-
16c
4GG##
4g--
4A-
4c
---------
4GG
4E
8A-
16c
4AA
4f
4A-
4c

그런데... b 를 ++ 하면 c 가 되는 게 아니라 cc 가 되어야 하는 거 아닌가요? 한 옥타브 높아지는... (음악에 문외한이라 확실치 않습니다만 ^^;) 만일 그 처리까지 해주려면 그때는 $up{$2} 또는 $down{$2} 라고 쓸 자리를 차라리 up($2) down($2) 로 쓰고 up 과 down 서브루틴을 만들어주는 게 나을 것 같습니다.

좋은 하루 되세요!

eventia의 이미지

고맙습니다.
또 처음보는 형태가 나오는군요. 잘 기억해 두어야겠네요. ^^
## 는 한음이 올라가는 거라(옥타브가 아니라..) B 에서 C 로, 반대로 -- 는 한음 내려가는 거라 C 에서 B 로 바뀝니다.
기본옥타브보다 하나 위는 c -> cc 로 쓰기로 약속이 된 거라 그 상태에서 한음 올리고 내리는 것은 dd, bb 로 쓰는 것이고, 반음은 # 과 - 를 그대로 붙여서 사용합니다. ^^

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.