C#
1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4using UnityEngine.Networking; 5 6public class htmlget : MonoBehaviour { 7 8void Start () { 9 StartCoroutine(GetText()); 10 } 11 12 IEnumerator GetText() 13 { 14 UnityWebRequest www = UnityWebRequest.Get(link); 15 yield return www.SendWebRequest(); 16 17 if (www.isNetworkError || www.isHttpError) 18 { 19 Debug.Log(www.error); 20 } 21 else 22 { 23 byte[] results = www.downloadHandler.data; 24 } 25 26System.Text.RegularExpressions.Regex num = 27 new System.Text.RegularExpressions.Regex( 28 @"[0-9]+", 29 System.Text.RegularExpressions.RegexOptions.IgnoreCase 30 | System.Text.RegularExpressions.RegexOptions.Multiline); 31 32System.Text.RegularExpressions.Regex alphabet = 33 new System.Text.RegularExpressions.Regex( 34 @"[a-zA-Z]+", 35 System.Text.RegularExpressions.RegexOptions.IgnoreCase 36 | System.Text.RegularExpressions.RegexOptions.Multiline); 37 38 39バイナリーデータの中身(例) 40 41あいうえお 4212345 43 44かきくけこ 4512345 46 47ABCDE 48 49あいうえお 5012345 51 52かきくけこ 5312345 54 55```### 前提・実現したいこと 56 57バイナリーデータから 58アルファベットの位置までの数字(ABCDEより上の位置の数字)を正規表現で全てマッチさせて 59MatchCollectionを作成しそれを配列に変換したいのですが 60 611.正規表現だけでそれが可能かどうか 62 632.一度アルファベットの位置(ABCDEの位置)を取得して正規表現以外でその位置までで検索を止める方法 64 65どちらのやり方でできるのか教えてほしいです。 66 67### 発生している問題・エラーメッセージ 68 69正規表現で数字をマッチさせようとするとアルファベットの位置(ABCDE)より下の位置の数字までマッチさせてしまう。 70 71### 試したこと 72 73正規表現一行で 74アルファベットの位置(ABCDE)を末尾指定$マーク等でアンカーをつけたりしたがそうすると数字もマッチしなくなる。 75 76大雑把な例 77「0-9」+[a-zA-Z]+$ 78 79### 補足情報(FW/ツールのバージョンなど) 80 81 82 83ここにより詳細な情報を記載してください。
新参者なのでよくわかっていませんが、
回答を書く前に質問への追記・修正依頼をすることが推奨されていますか?
(齟齬をなくそうという意図でしょうか?回答0のままコメント欄が伸びている質問を多く見かけます。)
↓回答は回答欄に入力しましょう に従い、先に回答を書いてしまいました。
回答欄にも書きましたが、文字、文字列、数字、アルファベットの仕様をもう少し補足して下さい。
(できればcodeブロックを使っていただけないでしょうか。)
* 複数行の文字列がstringなのかList<string>なのか?
* ファイルから引っ張るのか、コード内埋め込みなのか、別アプリから通信で取るデータなのか?
* 取得したい数字は全角/半角含んで良いのか?
* stringで取りたいのかchar配列で取りたいのか?
* 正規表現はmustか?
文字列をSelectもしくはSelectManyで文字として射影して、
Char.IsNumberやChar.IsDigit、Char.IsLetterやChar.IsUpper、Char.IsLowerを使うのも手です。
回答ありがとうございます!より詳しく編集しましたのでご指導よろしくお願いします!
正規表現でマッチさせたい情報にマッチさせるregexは作れて全てマッチさせる事は出来たのですが途中で検索を止めたりすることができなくて困っています・・・
> 新参者なのでよくわかっていませんが、
回答を書く前に質問への追記・修正依頼をすることが推奨されていますか?
例えば、情報不足の質問に対し、回答者が想像を膨らませて回答すると、想像が違っていた場合は的外れな回答になって混乱を招くばかりということになり勝ちなので、不明点はきちんと確認して質問者さんに質問欄を編集して情報を追記してもらうべきと思います。
他に「XY問題」になっていて、いくら回答してもいっこうに解決しないというケースもよくあります。(XY問題が何か不明ならググってください)
それゆえここが「質問への追記・修正の依頼」として提供されていると理解しています。
「XY問題」ググりました。すごく心当たりがあります。大変参考になりました。
マズローのハンマーですね。「金槌しか持っていなければ、全ての問題は釘に見えてくる」
Linqにこだわるのも、正規表現にこだわるのも止めてみます。
バイナリーデータの仕様について、再度確認させてください。
* 改行コードはどのように入っていますか?
* ABCDEは、必ず同じキーワードでしょうか?
* ABCDEは、必ず単数とわかっていますか?
* ABCDEより前の数値がすべて半角の12345ですし、ABCDEより後の数値も12345なのですが、
12345,12345を取得できれば良いですか。
申し訳ないのですがバイナリーデータがどのようなものか私がよく理解していないので、あれから試してみた事、やりたい事を書きます。
バイナリーデータから正規表現でマッチするときに\nで改行文字をマッチさせる事ができます。空白文字も\sでマッチさせることができたのでHTMLファイルとテキストファイルのような構造になっていると思います(間違ってる可能性大なので参考程度にお願いします)
*ABCDEは必ず同じキーワードで単数です。
*数字はすべて半角です。
*ABCDEより前の位置にある数字を取得したいです。
*ABCDEより後の位置にある数字は必要ないのでマッチさせたくないです。
私のやりたい事がrtazakiさんが最初に書いてくれたソースの中の.TakeWhileと.Whereを使う事で目的を果たせそうな気がします。
試してみた事は
バイナリーデータから直接.takewhile.Wheleを使おうとしたらエラーになる
var get = www.downloadHandler.text.
TakeWhile(line => !stop.IsMatch(line)).
Where(target => r.IsMatch(target));
で試すと!stop.IsMatch(line)).の(line)の箇所でCS1503:引数1:はcharから
stringへ変換する事ができません。となる
なので一旦バイナリーデータから数字とアルファベットをマッチさせてから
.takewhile.Wheleを使おうとしたのですが上手くできなかったです。
正規表現でregexを作りmatchesでバイナリーデータからマッチコレクションmcを作る
マッチコレクションmcの中身が
12345
12345
ABCDE
12345
12345
であることを確認してforを使ってmcの中身を文字列にして配列に変換する
var hairetu = new string[mc.Count];
for (int i = 0; i < hairetu.Length; i++)
{
hairetu[i] = mc[i].ToString();
}
そしてhairetuに対して.takewhile.Wheleを試してみてもうまくいきませんでした。
var gool = hairetu.
TakeWhile(line => !stop.IsMatch(line)).
Where(target => r.IsMatch(target));
1番やりたい事はバイナリーデータから正規表現で目的の配列を作るです。
hairetu[0] = 12345
hairetu[1] = 12345 という感じです。
もし直接バイナリーデータから配列が作れない時はMatchesを使い
マッチコレクションを作ってから配列に変換したいと考えています。
プログラミングの知識が未熟で説明も下手ですがご教示くださると助かります。
> HTMLファイルとテキストファイルのような構造になっていると思います(間違ってる可能性大なので参考程度にお願いします)
ひょっとして JSON 文字列になっているとかでは? だとすると、XY問題になっていると思います。
バイナリデータ: 包含関係の罠付きなのでご注意ください。
バイナリでググってみるとわかりますが、コンピューターが扱えるすべてのデータ=バイナリデータなので、テキストデータはバイナリーデータに含まれます。スクレイピングしたデータがバイナリーデータというのはその意味で「バイナリ」と言っています。(テキストしか送受信できないWebシステムって、使い道として限定的過ぎますよね?)
ところが、実際に扱うものがすべてバイナリだと本当に面倒くさいんですよ。今回のようなケースで、至高の正規表現マスター(笑)が「2回に分けずとも1回で目的のデータを取得してみせた」としても、究極のLinqプログラマー(笑)が、「それだと1回で取得するメモリサイズが大きいとソフトが死ぬので、ある程度の大きさごとに分割して、目的のデータを逐一返すのが真理」とか言っちゃっても、
普通のWebプログラマーならば受信したデータ=Json(もしくはXML)と分かっているので、適切なパーサーを用意するだけで目的を達成できてしまうのです。
Jsonであれば、System.Text.JsonもしくはNewtonsoft.Jsonをnugetして、そのバイナリをシリアライズ
してみてください。
ヒントを出しておきます: スクレイピングしたデータにはそれを納めるためのデータ構造があります。
c# json シリアライズ クラス
回答2件
あなたの回答
tips
プレビュー