回答編集履歴

4

プログラムに補足コメント

2023/10/19 05:31

投稿

otn
otn

スコア85783

test CHANGED
@@ -21,8 +21,8 @@
21
21
  import re
22
22
 
23
23
  def foo(m):
24
- l = len(m.group(1))
24
+ l = len(m.group(1)) # 1つめの括弧内の \ の連続の個数
25
- tail = m.group(2)
25
+ tail = m.group(2) # 2つめの括弧内の数字列。? 付きなので数字は無いかも知れずその場合は None
26
26
  if l % 2 == 0:
27
27
  if tail is None:
28
28
  tail = ""
@@ -30,7 +30,7 @@
30
30
  if tail is None:
31
31
  tail = "\\" # 奇数個の \ の後に数字が来ないケース
32
32
  else:
33
- tail = r[int(tail)] # 実際は範囲チェック要
33
+ tail = r[int(tail)] # 数字を添え字にしてリストから文字列取得。実際は範囲チェック要
34
34
  return "\\"*(l//2)+tail
35
35
 
36
36
 

3

細かい補足

2023/10/19 02:17

投稿

otn
otn

スコア85783

test CHANGED
@@ -14,9 +14,9 @@
14
14
  質問のコードを全く無視して書くとこんな感じでしょうか。
15
15
  「奇数個の`\`の後に数字が続かないケース」の対応が不明なのでそこは適当に書いてます。
16
16
  ```Python
17
- s = r"o:(\1) x:(\\1) o:(\\\1) x:(\\\\1) o:(\\\\\1) (\\\\\n)"
17
+ s = r"o:(\1) x:(\\1) o:(\\\1) x:(\\\\1) o:(\\\\\1) (\\\\\n)" #変換対象
18
- t = r"o:(A) x:(\1) o:(\A) x:(\\1) o:(\\A) (\\\n)"
18
+ t = r"o:(A) x:(\1) o:(\A) x:(\\1) o:(\\A) (\\\n)" # こうなって欲しい
19
- r = ["","A","B"]
19
+ r = ["","A","B"] # \数字 の置換対象リスト
20
20
 
21
21
  import re
22
22
 

2

回答例追加

2023/10/19 02:03

投稿

otn
otn

スコア85783

test CHANGED
@@ -9,3 +9,40 @@
9
9
 
10
10
  `Correct Result : o:(A) x:(\1) o:(\A) x:(\\1) o:(\\A)`
11
11
  に置換したいのだと思いますが、置換の規則が不明です。日本語で書けますか?
12
+
13
+ ## 追記
14
+ 質問のコードを全く無視して書くとこんな感じでしょうか。
15
+ 「奇数個の`\`の後に数字が続かないケース」の対応が不明なのでそこは適当に書いてます。
16
+ ```Python
17
+ s = r"o:(\1) x:(\\1) o:(\\\1) x:(\\\\1) o:(\\\\\1) (\\\\\n)"
18
+ t = r"o:(A) x:(\1) o:(\A) x:(\\1) o:(\\A) (\\\n)"
19
+ r = ["","A","B"]
20
+
21
+ import re
22
+
23
+ def foo(m):
24
+ l = len(m.group(1))
25
+ tail = m.group(2)
26
+ if l % 2 == 0:
27
+ if tail is None:
28
+ tail = ""
29
+ else:
30
+ if tail is None:
31
+ tail = "\\" # 奇数個の \ の後に数字が来ないケース
32
+ else:
33
+ tail = r[int(tail)] # 実際は範囲チェック要
34
+ return "\\"*(l//2)+tail
35
+
36
+
37
+ w = re.sub(r"(?<!\\)((?:\\)+)(\d+)?",foo,s)
38
+ # w = re.sub(r"((?:\\)+)(\d+)?",foo,s) # 多分こっちで十分
39
+ print("変換前 ",s)
40
+ print("変換後 ",w)
41
+ print("目標値 ",t)
42
+
43
+
44
+ 結果:
45
+ 変換前 o:(\1) x:(\\1) o:(\\\1) x:(\\\\1) o:(\\\\\1) (\\\\\n)
46
+ 変換後 o:(A) x:(\1) o:(\A) x:(\\1) o:(\\A) (\\\n)
47
+ 目標値 o:(A) x:(\1) o:(\A) x:(\\1) o:(\\A) (\\\n)
48
+ ```

1

タイプ漏れ修正

2023/10/18 15:08

投稿

otn
otn

スコア85783

test CHANGED
@@ -1,6 +1,6 @@
1
1
  駄目な理由としては、一旦`?`を無視すると、
2
2
  「直前が`\`でなく、`\`が偶数個で、直後が`\`でない」という正規表現に「`\1`」をつないでいるので、
3
- 「直前が`\`でなく、`\`が偶数個で、直後が`\`でないが、直後が\1'」という、矛盾を含むために何にもマッチしない正規表現になっています。
3
+ 「直前が`\`でなく、`\`が偶数個で、直後が`\`でないが、直後が`\1`」という、矛盾を含むために何にもマッチしない正規表現になっています。
4
4
  なので、`r"?\\1"`の`?`が効いて前の部分が無い場合になり、`regex_str = r"\\1"`と等価です。
5
5
  ちょっとはしょった説明ですが、多分おわかりになると思います。
6
6