﻿<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>正規表現  |  Web Creators Hub</title>
	<atom:link href="https://web-creators-hub.com/category/%E6%AD%A3%E8%A6%8F%E8%A1%A8%E7%8F%BE/feed/" rel="self" type="application/rss+xml" />
	<link>https://web-creators-hub.com</link>
	<description>WEB技術などの情報をわかりやすく配信するメディア</description>
	<lastBuildDate>Wed, 08 Feb 2023 01:56:31 +0000</lastBuildDate>
	<language>ja</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>https://wordpress.org/?v=4.8.2</generator>
	<item>
		<title>【最短マッチ】正規表現で手前の文字列のみ取得したい場合は特性変更できる「？」を使う</title>
		<link>https://web-creators-hub.com/php/pattern/</link>
		<pubDate>Tue, 07 May 2019 14:40:45 +0000</pubDate>
		<dc:creator><![CDATA[taizo]]></dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[正規表現]]></category>

		<guid isPermaLink="false">https://web-creators-hub.com/?p=286</guid>
		<description><![CDATA[正規表現最短マッチ 正規表現を覚えたてのときぶち当たる壁があります。取得したい場所を指定してしているのに要らないところまで取得してしまう。例...]]></description>
				<content:encoded><![CDATA[<p><img src="https://web-creators-hub.com/__wordpress/wp-content/uploads/2019/05/pattern_main.png" alt="" width="700" height="350" class="alignnone size-full wp-image-297" srcset="https://web-creators-hub.com/__wordpress/wp-content/uploads/2019/05/pattern_main.png 700w, https://web-creators-hub.com/__wordpress/wp-content/uploads/2019/05/pattern_main-300x150.png 300w, https://web-creators-hub.com/__wordpress/wp-content/uploads/2019/05/pattern_main-320x160.png 320w" sizes="(max-width: 700px) 100vw, 700px" /></p>
<h2>正規表現最短マッチ</h2>
<p>正規表現を覚えたてのときぶち当たる壁があります。取得したい場所を指定してしているのに要らないところまで取得してしまう。例ではhtmlのclass名のみ取得したいときぶち当たります。</p>
<pre class="brush: xml; title: ; notranslate">
&lt;div class=&quot;test&quot;&gt;&lt;div class=&quot;test__in&quot;&gt;test&lt;/div&gt;&lt;/div&gt;
</pre>
<p>class「test」のみ取得したいとき</p>
<pre class="brush: php; title: ; notranslate">
/class=\&quot;(.*)\&quot;/
</pre>
<p>PHPでは</p>
<pre class="brush: php; title: ; notranslate">
&lt;?php
 $source = '&lt;div class=&quot;test&quot;&gt;&lt;div class=&quot;test__in&quot;&gt;test&lt;/div&gt;&lt;/div&gt;';
 $pattern = '/class=\&quot;(.*)\&quot;/';
 
 preg_match($pattern,$source, $m);

?&gt;
</pre>
<p>こんな感じで書いたとします。しかし結果は</p>
<p><img class="alignnone size-full wp-image-287" src="https://web-creators-hub.com/__wordpress/wp-content/uploads/2019/05/pattern.jpg" alt="" width="501" height="146" srcset="https://web-creators-hub.com/__wordpress/wp-content/uploads/2019/05/pattern.jpg 501w, https://web-creators-hub.com/__wordpress/wp-content/uploads/2019/05/pattern-300x87.jpg 300w, https://web-creators-hub.com/__wordpress/wp-content/uploads/2019/05/pattern-320x93.jpg 320w" sizes="(max-width: 501px) 100vw, 501px" /></p>
<p>になってしまいます。よく考えると確かにそうなります。<br />
しかし解決方法がなかなか見当たらないのです。ググりたいけどどういう状況かを説明できないので、はじめの場合は苦戦します。実はこの状況「最短マッチ」といいます。私は「正規表現　手前のみ取得」でたどり着きました。</p>
<h2>.*?</h2>
<p>「最短マッチ」させるためには一般的には以下のように書きます。</p>
<pre class="brush: php; title: ; notranslate">
/class=\&quot;(.*?)\&quot;/
</pre>
<p>PHPでは</p>
<pre class="brush: php; title: ; notranslate">
&lt;?php
 $source = '&lt;div class=&quot;test&quot;&gt;&lt;div class=&quot;test__in&quot;&gt;test&lt;/div&gt;&lt;/div&gt;';
 $pattern = '/class=\&quot;(.*?)\&quot;/';
 
 preg_match($pattern,$source, $m);

?&gt;
</pre>
<p>？(はてな)を加えるだけでなぜか取得できます。</p>
<h2>なぜ.*?で取得できるのか</h2>
<p>*(アスタリスク)や？(はてな)は量指定子文字といい、前の文字を何回でてくるか指定することができる文字です。</p>
<table>
<thead>
<tr>
<th style="text-align: center;">量指定子</th>
<th style="text-align: center;">説明</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align: center;">*</td>
<td style="text-align: center;">0回以上の繰り返しにマッチ</td>
</tr>
<tr>
<td style="text-align: center;">?</td>
<td style="text-align: center;">0回または1回の出現にマッチする表現</td>
</tr>
<tr>
<td style="text-align: center;">+</td>
<td style="text-align: center;">1回以上の繰り返しにマッチ</td>
</tr>
<tr>
<td style="text-align: center;">{n}</td>
<td style="text-align: center;">n回の繰り返しにマッチする表現</td>
</tr>
<tr>
<td style="text-align: center;">{n,}</td>
<td style="text-align: center;">n回以上の繰り返しにマッチする表現</td>
</tr>
<tr>
<td style="text-align: center;">{n,m}</td>
<td style="text-align: center;">n回以上m回以下の繰り返しにマッチする表現</td>
</tr>
</tbody>
</table>
<p>量指定子はデフォルトで「できるだけ長い文字列にマッチさせる特性(最長一致)」をもっています。そのため「*(アスタリスク)」はできる長く取得するため初めに書いたように予定していないところまで取得したのです。この特性を変更させるのが「？(はてな)」です。量指定子の後ろに「？」をつけると特性が「できるだけ短い文字列にマッチする特性（最短一致）」に変わります。上記の量指定子だけ覚えていると意味がわかりませんが、「？」には特性を変更できる特殊な能力があると覚えておくと便利に利用できます。</p>
<div class="alert">特性変更<br />
.* 最長一致<br />
↓<br />
.*? 最短一致</div>
<h2>連続して取得したいとき</h2>
<p>以下のソースのクラスを全て取得したいときはどのようにすればいいでしょうか。</p>
<pre class="brush: xml; title: ; notranslate">
&lt;div class=&quot;test&quot;&gt;&lt;div class=&quot;test__in&quot;&gt;test&lt;/div&gt;&lt;/div&gt;
</pre>
<p>「test」「test__in」も取得したい。</p>
<p>PHPの場合では連続マッチできる関数があります。<br />
preg_match　単一<br />
↓<br />
preg_match_all　連続</p>
<pre class="brush: php; title: ; notranslate">
&lt;?php
 $source = '&lt;div class=&quot;test&quot;&gt;&lt;div class=&quot;test__in&quot;&gt;test&lt;/div&gt;&lt;/div&gt;';
 $pattern = '/class=\&quot;(.*?)\&quot;/';
 
 preg_match_all($pattern,$source, $matches, PREG_OFFSET_CAPTURE);

 foreach($matches[1] as $result){
     echo str_replace(&quot; &quot;,&quot;&lt;br&gt;&quot;,$result[0]) . &quot;&lt;br&gt;&quot;;
 }
 
?&gt;
</pre>
]]></content:encoded>
			</item>
	</channel>
</rss>
