質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
正規表現

正規表現とは特定の文字列によるパターンマッチングを行う際に用いられる宣言型プログラミングです。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

3回答

2816閲覧

文字列を分割したいけど区切り文字は残したい

Kozyma

総合スコア5

正規表現

正規表現とは特定の文字列によるパターンマッチングを行う際に用いられる宣言型プログラミングです。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2021/12/14 03:57

実現したいこと

アルファベットと数字からなるIDを分割したいです。
たとえば「H1-29H1-02」というIDがあり、これを「アルファベット+数字」、つまり「H1-29」と「H1-02」に分けたいです。

現在、IDは複数の月次ファイルに入力されています。
それを1つのExcelに貼り付けて、重複を削除してから、IDを分割するという作業を行っています。

対象ID(サンプル)

操作対象IDのサンプルです。アルファベットはA~Zまで、数字は2~3桁まであります。

H1-29H1-02
C1-68B1-02
Q1-23A1-02
T1-02T1-02
H1-108P1-02
L1-68Y1-53
C1-109A1-02
・・・

試したこと

####Excel編
「データ」→「区切り位置」で5文字目まで区切り、前半の数字2桁のものをまず抽出。
そこから、後半の文字列のうち数字から始まっているもの(前半が数字3桁のもの)をソートし、1文字目(数字)と後半を抽出。
抽出した数字を前半の文字列と結合し、数字3桁のIDを完成させる。

・・・とやっていきましたが、ファイル数が多いので気が遠くなりそうです。

####Python編
「Python:正規表現で文字列を分割するのがre.split」
https://sigotonosozai.com/2020/10/21/resplit/

上記の記事より、re:splitと正規表現を用いれば、アルファベットで区切れることが分かりました。
ただし区切った文字が消えてしまうので、消さないようにするための処理が分からずに悩んでいます。

該当のソースコード

上記記事より該当箇所を引用しました。区切り文字が消えてしまいます。

python

1 2>>> import re 3>>> umaibo_taste = re.split('[A-Z]','chessANDmentai') 4>>> print(umaibo_taste) 5['chess', '', '', 'mentai']

###知りたいこと
ExcelもしくはPythonを用いて、効率的に文字を区切る方法についてアドバイスをいただければ幸いです。

###動作環境
Excel2016
Python 3.8
を利用しています。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2021/12/14 04:24

「対象ID(サンプル)」にある7行のテキストを入力が入力されるときに、最終的に得たい出力はどのようなものでしょうか?
Kozyma

2021/12/14 04:29

質問をご覧くださりありがとうございます。 A列 B列 C列 H1-29H1-02 H1-29 H1-02 というように出力できればと考えています。
退会済みユーザー

退会済みユーザー

2021/12/14 06:41

ご返答どうもです。回答しました。
guest

回答3

0

ベストアンサー

splitで区切り文字を残す方法も有りますが、findall使った方が楽そうです。

Python

1dst = re.findall(r'[^-]+-[0-9]+', 文字列)

複数行一気に処理するなら、事前に空白文字を潰します。

Python

1src = src.strip() 2src = ''.join(src.split())

投稿2021/12/14 04:24

編集2021/12/14 04:27
LouiS0616

総合スコア35668

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Kozyma

2021/12/14 04:54

```python import re ID_list=["H1-29H1-02", "C1-68B1-02", "Q1-23A1-02", "T1-02T1-02", "H1-108P1-02", "L1-68Y1-53", "C1-109A1-02"] for c in ID_list: dst = re.findall(r'[^-]+-[0-9]+',c) print(dst) ``` で出力できました!! ありがとうございます!!
Kozyma

2021/12/14 04:59

出力結果・・・ ['H1-29', 'H1-02'] ['C1-68', 'B1-02'] ['Q1-23', 'A1-02'] ['T1-02', 'T1-02'] ['H1-108', 'P1-02'] ['L1-68', 'Y1-53'] ['C1-109', 'A1-02']
Kozyma

2021/12/14 05:12

複数行一気にもやってみます!
Kozyma

2021/12/15 03:03 編集

すいません、回答スレッドを間違えました!!
guest

0

ご質問に

「Python:正規表現で文字列を分割するのがre.split」

とあったので、re.split を使うコードを考えてみました。

Python3

1import re 2 3 4lines = '''H1-29H1-02 5C1-68B1-02 6Q1-23A1-02 7T1-02T1-02 8H1-108P1-02 9L1-68Y1-53 10C1-109A1-02'''.splitlines() 11 12delimiter = r'(?<=[0-9])(?=[A-Z])' 13 14for line in lines: 15 print(re.split(delimiter, line)) 16

出力結果:

['H1-29', 'H1-02']

['C1-68', 'B1-02']
['Q1-23', 'A1-02']
['T1-02', 'T1-02']
['H1-108', 'P1-02']
['L1-68', 'Y1-53']
['C1-109', 'A1-02']

サンプル ???? replit.com/@kilesa/tera-373722

投稿2021/12/14 06:40

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Kozyma

2021/12/15 01:01

kilesaさま、ご丁寧なアドバイスをありがとうございます。サンプルも用意してくださり、初心者には大変ありがたいです。ppaulさまからいただいたアドバイスのコードとちょっと似ているところ、違うところがあり、勉強になります! 別ページのサンプルも拝見しました。こういうことが出来るサイトもあるんですね。助け合いのシステムが素晴らしいです。。。
Kozyma

2021/12/15 03:10

複数行(2万6千行ほど)を処理したところ、なぜか後ろから900行弱ほどが分割出来ませんでした。 分割できなかった900行弱を別のファイルに貼り付けて処理しても出力出来ませんでした。 ほかのIDと何が違うのか、文字面をみていても糸口が見つかりません。何かアドバイスをいただければ幸いです。 <分割されなかったID(一部)> A6-24H1-58 C5-25H1-76 E1-02H1-77 C2-02H1-103 C1-17H1-35 A3-18H1-52 D6-25H1-89 E4-07H1-82 以下、記載したコードになります。 これを実行すると、空のcsvが出力されてしまいました。 --- import re import csv lines = '''A6-24H1-58 C5-25H1-76 E1-02H1-77 C2-02H1-103 C1-17H1-35 A3-18H1-52 D6-25H1-89 E4-07H1-82'''.splitlines() delimiter = r'(?<=[0-9])(?=[A-Z])' #出力結果をリストに追加 list=[] for line in lines: list.append(re.split(delimiter, line)) #csvファイルに出力 f=open("リスト.csv", mode="w", newline="") writer=csv.writer(f) for data in list: writer.writerow(data) f.close ---
guest

0

以下のようにします。

python

1import re 2 3text = '''H1-29H1-02 4C1-68B1-02 5Q1-23A1-02 6T1-02T1-02 7H1-108P1-02 8L1-68Y1-53 9C1-109A1-02''' 10 11lines = text.split('\n') 12print([r 13e.search(r'(\D+\d+-\d+)(\D+\d+-\d+)', line).groups() for line in lines])

実行結果

python

1>>> lines = text.split('\n') 2>>> print([re.search(r'(\D+\d+-\d+)(\D+\d+-\d+)', line).groups() for line in lines]) 3[('H1-29', 'H1-02'), ('C1-68', 'B1-02'), ('Q1-23', 'A1-02'), ('T1-02', 'T1-02'), ('H1-108', 'P1-02'), ('L1-68', 'Y1-53'), ('C1-109', 'A1-02')]

投稿2021/12/14 04:23

ppaul

総合スコア24670

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Kozyma

2021/12/14 05:12

ppaulさま、いつもアドバイスをくださり、ありがとうございます。 いただいたコードを入力したら、ご掲載いただいたとおりの出力となりました。 シングルクォーテーションを3つつなげて使う使い方を知りませんでした。これだとエクセルからセルをそのままコピーして使えるので便利ですね!大変勉強になりました。 三連引用符を使った複数行の文字列の記述 https://www.javadrive.jp/python/string/index3.html 上述のLouiS0616さまからいただいたコードの出力結果(各要素が1つのリストになっている)と少し異なった形になるのですね。これはタプルになるのでしょうか。。
ppaul

2021/12/14 09:21

そうです。タプルです。
Kozyma

2021/12/15 00:54

ご返信ありがとうございます!この後別の処理をするのにリストとタプルとどちらが使いやすいかやってみたいと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問