Jadual Kandungan
[PHP源码阅读]strpos、strstr和stripos、stristr函数,strposstristr
strpos
例子
strpos核心源码
查找函数
strstr
strstr核心源码
stripos
stristr
核心源码
总结
Rumah pembangunan bahagian belakang tutorial php [PHP源码阅读]strpos、strstr和stripos、stristr函数,strposstristr_PHP教程

[PHP源码阅读]strpos、strstr和stripos、stristr函数,strposstristr_PHP教程

Jul 12, 2016 am 08:52 AM
rentetan

[PHP源码阅读]strpos、strstr和stripos、stristr函数,strposstristr

strpos

<span>mixed</span> <span>strpos</span> ( <span>string</span> <span>$haystack</span>, <span>mixed</span> <span>$needle</span> [, int <span>$offset</span> = 0 ] )
Salin selepas log masuk

如果offset指定了,查找会从offset的位置开始。offset不能为负数。

返回needle第一次出现在haystack的位置。如果在haystack中找不到needle,则返回FALSE。

needle,如果needle不是字符串,它会被转换成整型数值并赋值为该数值的ASCII字符。请看下面例子。

例子

<span>$str</span> = "hello"<span>;
</span><span>$pos</span> = <span>strpos</span>(<span>$str</span>, 111<span>);
</span><span>//</span><span> 111的ASCII值是o,因此$pos = 4</span>
Salin selepas log masuk

strpos核心源码

<span>if</span> (Z_TYPE_P(needle) ==<span> IS_STRING) {
     </span><span>if</span> (!<span>Z_STRLEN_P(needle)) {
          php_error_docref(NULL TSRMLS_CC, E_WARNING, </span><span>"</span><span>Empty needle</span><span>"</span><span>);
          RETURN_FALSE;
     }

     </span><span>//</span><span> 调用php_memnstr函数查找needle</span>
     found = php_memnstr(haystack +<span> offset,
                            Z_STRVAL_P(needle),
                            Z_STRLEN_P(needle),
                            haystack </span>+<span> haystack_len);
     } </span><span>else</span><span> {
          </span><span>//</span><span> 如果不是字符串,转换成数字并赋值为该数字的ASCII字符。</span>
          <span>if</span> (php_needle_char(needle, needle_char TSRMLS_CC) !=<span> SUCCESS) {
               RETURN_FALSE;
          }
          </span><span>//</span><span>设置结束字符</span>
          needle_char[<span>1</span>] = <span>0</span><span>;
          found </span>= php_memnstr(haystack +<span> offset,
                            needle_char,
                            </span><span>1</span><span>,
                            haystack </span>+<span> haystack_len);<br />    }
}</span>
Salin selepas log masuk

有一点要注意的是,如果needle不是字符串的话,会调用php_needle_char函数将needle转成整型数字并转换为其ASCII值。

查找函数

函数最后返回的是found,php_memnstr函数实现了查找的方法。那么再继续看看php_memnstr函数做了什么:

<span>#define</span> php_memnstr zend_memnstr
Salin selepas log masuk

php_memnstr是函数zend_memnstr的宏定义,查看zend_memnstr函数如下:

<span>static</span> inline <span>char</span> *<span>
zend_memnstr(</span><span>char</span> *haystack, <span>char</span> *needle, <span>int</span> needle_len, <span>char</span> *<span>end)
{
    </span><span>char</span> *p =<span> haystack;
    </span><span>char</span> ne = needle[needle_len-<span>1</span><span>];
    </span><span>if</span> (needle_len == <span>1</span><span>) {
        </span><span>return</span> (<span>char</span> *)memchr(p, *needle, (end-<span>p));
    }

    </span><span>if</span> (needle_len > end-<span>haystack) {
        </span><span>return</span><span> NULL;
    }

    </span><span>//</span><span> 第一个优化,只查找end - needle_len次</span>
    end -=<span> needle_len;

    </span><span>while</span> (p <=<span> end) {
        </span><span>//</span><span> 第二个优化,先判断字符串的开头和结尾是否一样再判断整个字符串</span>
        <span>if</span> ((p = (<span>char</span> *)memchr(p, *needle, (end-p+<span>1</span>))) && ne == p[needle_len-<span>1</span><span>]) {
            </span><span>if</span> (!memcmp(needle, p, needle_len-<span>1</span><span>)) {
                </span><span>return</span><span> p;
            }
        }

        </span><span>if</span> (p ==<span> NULL) {
            </span><span>return</span><span> NULL;
        }

        p</span>++<span>;
    }

    </span><span>return</span><span> NULL;
}</span>
Salin selepas log masuk

第一个优化,因为(char *)memchr(p, *needle, (end-p+1)是在end - needle_len + 1(即haystack_len+1)中查找,如果p为空,说明needle的第一个字符在p中从未出现过。

strstr

<span>string</span> <span>strstr</span> ( <span>string</span> <span>$haystack</span>, <span>mixed</span> <span>$needle</span> [, bool <span>$before_needle</span> = <span>false</span> ] )
Salin selepas log masuk

返回needle在haystack中第一次出现的位置到结束的字符串。

这个函数的区分大小写的。

如果needle在haystack中不存在,返回FALSE。

如果before_needle为true,则返回haystack中needle在haystack第一次出现的位置之前的字符串。

strstr核心源码

<span>if</span><span> (found) {
        </span><span>//</span><span> 计算出found的位置</span>
        found_offset = found -<span> haystack;
        </span><span>if</span><span> (part) {
            RETURN_STRINGL(haystack, found_offset, </span><span>1</span><span>);
        } </span><span>else</span><span> {
            RETURN_STRINGL(found, haystack_len </span>- found_offset, <span>1</span><span>);
        }
    }</span>
Salin selepas log masuk

strstr函数的前半部分跟strpos类似,区别在于strstr函数在找到位置后,需要返回haystack部分的字符串。part变量就是调用strstr函数时传递的before_needle变量。

stripos

<span>mixed</span> <span>stripos</span> ( <span>string</span> <span>$haystack</span>, <span>string</span> <span>$needle</span> [, int <span>$offset</span> = 0 ] )
Salin selepas log masuk

不区分大小写的strpos。实现方式跟下面的类似,主要是使用一份拷贝然后将需要比较的字符串转换成小写字符后进行再进行查找。

stristr

<span>string</span> <span>stristr</span> ( <span>string</span> <span>$haystack</span>, <span>mixed</span> <span>$needle</span> [, bool <span>$before_needle</span> = <span>false</span> ] )
Salin selepas log masuk

不区分大小写的strstr。

核心源码

<span>//</span><span> 拷贝一份haystack</span>
     haystack_dup =<span> estrndup(haystack, haystack_len);

    </span><span>if</span> (Z_TYPE_P(needle) ==<span> IS_STRING) {
        </span><span>char</span> *<span>orig_needle;
        </span><span>if</span> (!<span>Z_STRLEN_P(needle)) {
            php_error_docref(NULL TSRMLS_CC, E_WARNING, </span><span>"</span><span>Empty needle</span><span>"</span><span>);
            efree(haystack_dup);
            RETURN_FALSE;
        }
        orig_needle </span>=<span> estrndup(Z_STRVAL_P(needle), Z_STRLEN_P(needle));
        </span><span>//</span><span> 调用php_stristr函数找出orig_needle的值。</span>
        found =<span> php_stristr(haystack_dup, orig_needle,    haystack_len, Z_STRLEN_P(needle));
        efree(orig_needle);
    } </span><span>else</span><span> {
        </span><span>if</span> (php_needle_char(needle, needle_char TSRMLS_CC) !=<span> SUCCESS) {
            efree(haystack_dup);
            RETURN_FALSE;
        }
        needle_char[</span><span>1</span>] = <span>0</span><span>;

        found </span>= php_stristr(haystack_dup, needle_char,    haystack_len, <span>1</span><span>);
    }

    </span><span>if</span><span> (found) {
        found_offset </span>= found -<span> haystack_dup;
        </span><span>if</span><span> (part) {
            RETVAL_STRINGL(haystack, found_offset, </span><span>1</span><span>);
        } </span><span>else</span><span> {
            RETVAL_STRINGL(haystack </span>+ found_offset, haystack_len - found_offset, <span>1</span><span>);
        }
    } </span><span>else</span><span> {
        RETVAL_FALSE;
    }
    
    </span><span>//</span><span> 释放变量</span>
    efree(haystack_dup);
Salin selepas log masuk

可以知道,found是从php_stristr中得到的,继续查看php_stristr函数:

PHPAPI <span>char</span> *php_stristr(<span>char</span> *s, <span>char</span> *<span>t, size_t s_len, size_t t_len)
{
    php_strtolower(s, s_len);
    php_strtolower(t, t_len);
    </span><span>return</span> php_memnstr(s, t, t_len, s +<span> s_len);
}</span>
Salin selepas log masuk

这个函数的功能就是将字符串都转成小写之后调用php_mennstr函数来查找needle在haystack第一次出现的位置。

总结

因为strpos/stripos返回的是位置,位置从0开始计算,所以判断查找失败都用  === FALSE 更适合。

阅读PHP的源码收获挺多,一方面可以知道某个函数的具体实现原理是怎样的,另一方面可以学习到一些编程优化方案。

 

到此本文结束,如果还有什么疑问或者建议,可以多多交流,原创文章,文笔有限,才疏学浅,文中若有不正之处,万望告知。

如果本文对你有帮助,望点下推荐,谢谢^_^

www.bkjia.comtruehttp://www.bkjia.com/PHPjc/1125523.htmlTechArticle[PHP源码阅读]strpos、strstr和stripos、stristr函数,strposstristr strpos mixed strpos ( string $haystack , mixed $needle [, int $offset = 0 ] ) 如果offset指定了,查找...
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn

Alat AI Hot

Undresser.AI Undress

Undresser.AI Undress

Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover

AI Clothes Remover

Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool

Undress AI Tool

Gambar buka pakaian secara percuma

Clothoff.io

Clothoff.io

Penyingkiran pakaian AI

AI Hentai Generator

AI Hentai Generator

Menjana ai hentai secara percuma.

Artikel Panas

R.E.P.O. Kristal tenaga dijelaskan dan apa yang mereka lakukan (kristal kuning)
2 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌
Repo: Cara menghidupkan semula rakan sepasukan
4 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island Adventure: Cara mendapatkan biji gergasi
4 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌

Alat panas

Notepad++7.3.1

Notepad++7.3.1

Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina

SublimeText3 versi Cina

Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1

Hantar Studio 13.0.1

Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6

Dreamweaver CS6

Alat pembangunan web visual

SublimeText3 versi Mac

SublimeText3 versi Mac

Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Penjelasan terperinci tentang kaedah menukar jenis int kepada rentetan dalam PHP Penjelasan terperinci tentang kaedah menukar jenis int kepada rentetan dalam PHP Mar 26, 2024 am 11:45 AM

Penjelasan terperinci tentang kaedah menukar jenis int kepada rentetan dalam PHP Dalam pembangunan PHP, kita sering menghadapi keperluan untuk menukar jenis int kepada jenis rentetan. Penukaran ini boleh dicapai dalam pelbagai cara Artikel ini akan memperkenalkan beberapa kaedah biasa secara terperinci, dengan contoh kod khusus untuk membantu pembaca memahami dengan lebih baik. 1. Gunakan fungsi terbina dalam PHP strval(). PHP menyediakan fungsi terbina dalam strval() yang boleh menukar pembolehubah jenis yang berbeza kepada jenis rentetan. Apabila kita perlu menukar jenis int kepada jenis rentetan,

Bagaimana untuk menyemak sama ada rentetan bermula dengan aksara tertentu dalam Golang? Bagaimana untuk menyemak sama ada rentetan bermula dengan aksara tertentu dalam Golang? Mar 12, 2024 pm 09:42 PM

Bagaimana untuk menyemak sama ada rentetan bermula dengan aksara tertentu dalam Golang? Apabila pengaturcaraan di Golang, anda sering menghadapi situasi di mana anda perlu menyemak sama ada rentetan bermula dengan aksara tertentu. Untuk memenuhi keperluan ini, kita boleh menggunakan fungsi yang disediakan oleh pakej rentetan di Golang untuk mencapainya. Seterusnya, kami akan memperkenalkan secara terperinci cara menggunakan Golang untuk menyemak sama ada rentetan bermula dengan aksara tertentu, dengan contoh kod tertentu. Di Golang, kita boleh menggunakan HasPrefix daripada pakej rentetan

Bagaimana untuk menentukan sama ada rentetan Golang berakhir dengan aksara yang ditentukan Bagaimana untuk menentukan sama ada rentetan Golang berakhir dengan aksara yang ditentukan Mar 12, 2024 pm 04:48 PM

Tajuk: Bagaimana untuk menentukan sama ada rentetan berakhir dengan aksara tertentu dalam Golang Dalam bahasa Go, kadangkala kita perlu menentukan sama ada rentetan berakhir dengan aksara tertentu Ini adalah perkara biasa semasa memproses rentetan. Artikel ini akan memperkenalkan cara menggunakan bahasa Go untuk melaksanakan fungsi ini dan memberikan contoh kod untuk rujukan anda. Mula-mula, mari kita lihat cara untuk menentukan sama ada rentetan berakhir dengan aksara tertentu dalam Golang. Aksara dalam rentetan dalam Golang boleh diperoleh melalui pengindeksan, dan panjang rentetan itu boleh

Bagaimana untuk mengulangi rentetan dalam python_python mengulangi tutorial rentetan Bagaimana untuk mengulangi rentetan dalam python_python mengulangi tutorial rentetan Apr 02, 2024 pm 03:58 PM

1. Mula-mula buka pycharm dan masukkan halaman utama pycharm. 2. Kemudian buat skrip python baru, klik kanan - klik baru - klik pythonfile. 3. Masukkan rentetan, kod: s="-". 4. Kemudian anda perlu mengulang simbol dalam rentetan sebanyak 20 kali, kod: s1=s*20 5. Masukkan kod output cetakan, kod: print(s1). 6. Akhir sekali jalankan skrip dan anda akan melihat nilai pulangan kami di bahagian bawah: - diulang 20 kali.

Bagaimana untuk menyelesaikan masalah aksara Cina yang kacau apabila menukar perenambelasan kepada rentetan dalam PHP Bagaimana untuk menyelesaikan masalah aksara Cina yang kacau apabila menukar perenambelasan kepada rentetan dalam PHP Mar 04, 2024 am 09:36 AM

Kaedah untuk menyelesaikan masalah aksara Cina yang kacau apabila menukar rentetan perenambelasan dalam PHP Dalam pengaturcaraan PHP, kadangkala kita menghadapi situasi di mana kita perlu menukar rentetan heksadesimal kepada aksara Cina biasa. Walau bagaimanapun, dalam proses penukaran ini, kadangkala anda akan menghadapi masalah aksara Cina yang kacau. Artikel ini akan memberi anda kaedah untuk menyelesaikan masalah aksara Cina yang bercelaru apabila menukar perenambelasan kepada rentetan dalam PHP dan memberikan contoh kod khusus. Gunakan fungsi hex2bin() untuk penukaran heksadesimal PHP terbina dalam fungsi hex2bin() boleh menukar 1

Petua Padanan Rentetan PHP: Elakkan Ungkapan Disertakan Kabur Petua Padanan Rentetan PHP: Elakkan Ungkapan Disertakan Kabur Feb 29, 2024 am 08:06 AM

Petua Padanan Rentetan PHP: Elakkan Ungkapan Disertakan Kabur Dalam pembangunan PHP, pemadanan rentetan ialah tugas biasa, biasanya digunakan untuk mencari kandungan teks tertentu atau untuk mengesahkan format input. Walau bagaimanapun, kadangkala kita perlu mengelak daripada menggunakan ungkapan kemasukan yang tidak jelas untuk memastikan ketepatan padanan. Artikel ini akan memperkenalkan beberapa teknik untuk mengelakkan ungkapan kemasukan yang samar-samar semasa melakukan pemadanan rentetan dalam PHP dan memberikan contoh kod khusus. Gunakan fungsi preg_match() untuk padanan tepat Dalam PHP, anda boleh menggunakan preg_mat

Manipulasi rentetan PHP: cara praktikal untuk mengalih keluar ruang dengan berkesan Manipulasi rentetan PHP: cara praktikal untuk mengalih keluar ruang dengan berkesan Mar 24, 2024 am 11:45 AM

Operasi Rentetan PHP: Kaedah Praktikal untuk Mengalih Keluar Ruang Secara Berkesan Dalam pembangunan PHP, kita sering menghadapi situasi di mana kita perlu mengalih keluar ruang daripada rentetan. Mengalih keluar ruang boleh menjadikan rentetan lebih bersih dan memudahkan pemprosesan dan paparan data seterusnya. Artikel ini akan memperkenalkan beberapa kaedah yang berkesan dan praktikal untuk mengalih keluar ruang, dan melampirkan contoh kod tertentu. Kaedah 1: Gunakan fungsi PHP terbina dalam trim() fungsi terbina dalam PHP boleh mengalih keluar ruang pada kedua-dua hujung rentetan (termasuk ruang, tab, baris baharu, dsb.), yang sangat mudah dan mudah. untuk menggunakan.

Teknik PHP untuk memadam dua aksara terakhir rentetan Teknik PHP untuk memadam dua aksara terakhir rentetan Mar 23, 2024 pm 12:18 PM

Sebagai bahasa skrip yang digunakan secara meluas untuk membangunkan aplikasi web, PHP mempunyai fungsi pemprosesan rentetan yang sangat berkuasa. Dalam pembangunan harian, kita sering menghadapi operasi yang memerlukan pemadaman rentetan, terutamanya dua aksara terakhir rentetan. Artikel ini akan memperkenalkan dua teknik PHP untuk memadamkan dua aksara terakhir rentetan dan memberikan contoh kod khusus. Petua 1: Gunakan fungsi substr Fungsi substr dalam PHP digunakan untuk mengembalikan sebahagian daripada rentetan. Kita boleh mengalih keluar aksara dengan mudah dengan menentukan rentetan dan kedudukan permulaan

See all articles