Java UDP 统计字符串中某子串出现的次数

来源:互联网 发布:alchemy软件 编辑:程序博客网 时间:2024/06/06 16:29

import Java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.Net.DatagramSocket;
import java.net.InetAddress;

/**
 * 聊天对话,发送的时候同时也可以接受
 *
 */

class Chat1 implements Runnable{

 @Override
 public void run() {
  try {
   disPlay();
   
  } catch (Exception e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
  
 }
 public static void disPlay()throws Exception{
  DatagramSocket ds=new DatagramSocket();
  BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
  String line=null;
  while((line=br.readLine())!=null){
   if(line.equals("886")){
    break;
   }
   byte[] buf=line.getBytes();
   InetAddress is=InetAddress.getByName("192.168.49.88");
   DatagramPacket dp=new DatagramPacket(buf, buf.length, is,9009);
   String s=InetAddress.getLocalHost().toString();
   //String s1=InetAddress.getByName(s).toString();
   System.out.print(s+": ");
   ds.send(dp);
  }
 }
}
class Chat2 implements Runnable{

 @Override
 public void run() {
  try {
   disPlay();
   
  } catch (Exception e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
  
 }
 public static void disPlay() throws Exception{
  DatagramSocket ds=new DatagramSocket(9009);
  while(true){
   byte[] buf=new byte[1024];
   DatagramPacket dp=new DatagramPacket(buf, buf.length);
   
   ds.receive(dp);
   
   String host=dp.getAddress().getHostAddress();
   //int i=dp.getPort();
   String data=new String(dp.getData()).trim();
    System.out.println(host+":"+data);
   }
  }
  //ds.close();
 
}

public class ChatDemo {

 /**
  * @param args
  */
 public static void main(String[] args) {
  Chat1 c1=new Chat1();
  Chat2 c2=new Chat2();
  Thread t1=new Thread(c1);
  Thread t2=new Thread(c2);
  t1.start();
  t2.start();

 }

}


JDBC开发

JDBC的开发过程:
1. 首先建立数据库,插入表的记录,新建一个Java项目,在项目下建立lib文件,并把mysql驱动导入到Java项目中lib文件中。
2. 编写代码,并把mysql驱动加载到Java项目中,构建路径
推荐方法:class.froName(“com.mysql.jdbc.Driver”);
3. 建立连接
String url=”jdbc:mysql://localhost:3306/xsgl”:
String user=”root”:
Sting pass=”root”:
Connection con=DriverManager.getConnection(url,user,pass);
4. 创建Statement对象
Statement st=con.createStatement();
5. 执行
ResultSet rs=st.excuteQuery(sql);
6. 遍历结果集
while(rs.next()){
}
7. 关闭资源
rs.close();
st.close();
con.close()
注意:关闭资源之前,必须判断rs,st,con是否为空,如果为空就不需要关闭,否则关闭资源。//if(rs!=null || st!=null || con!=null){
//关闭资源
rs.close();
st.close();
con.close()
}//if尽可能的写在finally中,确保资源的释放
Connection对象是非常稀有的资源,用完后必须马上释放,如果Connection不能及时、正确的关闭,极易导致系统宕机。Connection的使用原则是尽量晚创建,尽量早的释放。
为了确保资源的释放,尽量把资源释放代码放到finally语句块中。

Connection对象常用的方法有:
• createStatement():创建向数据库发送sql的statement对象。
• prepareStatement(sql) :创建向数据库发送预编译sql的PrepareSatement对象。
• prepareCall(sql):创建执行存储过程的callableStatement对象。 
• setAutoCommit(boolean autoCommit):设置事务是否自动提交。 
• commit() :在链接上提交事务。
• rollback() :在此链接上回滚事务。
Statement对象常用方法:
• execute(String sql):用于向数据库发送任意sql语句
• executeQuery(String sql) :只能向数据发送查询语句。
• executeUpdate(String sql):只能向数据库发送insert、update或delete语句
• addBatch(String sql) :把多条sql语句放到一个批处理中。
• executeBatch():向数据库发送一批sql语句执行。 
ResultSet对象常用的结果集进行滚动的方法:
• next():移动到下一行
• Previous():移动到前一行
• absolute(int row):移动到指定行
• beforeFirst():移动resultSet的最前面。
• afterLast() :移动到resultSet的最后面。
提取代码到配置文件中,文件名.properties
在实际开发中为了避免数据库改动,需要把一些必要的代码写到一个单独的配置文件中,这就简化了对大量代码的改动:如
在驱动连接数据库时,String url=”jdbc:mysql://localhost:3306/xsgl”:
String user=”root”:
Sting pass=”root”:
像这些代码都可以提取到配置文件中,在配置文件中就可以写为user=root
在写代码需要使用配置文件的内容时,
InputStream in=DBManager.class.getClassLoader().getResourceAsStream("db.properties");
Properties pro=new Properties();
try {
pro.load(in); 
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
driver=pro.getProperty("driver");
url=pro.getProperty("url");
user=pro.getProperty("user");
password=pro.getProperty("password");
}catch(Exception e){
}
通过输入流就可以读取获取到配置文件的内容,附加给创建的成员变量,并加以使用
当系统运行时,需要读取一下配置文件,以获取配置文件的内容

多线程
多线程是为了同步完成多项任务,不是为了提高运行效率,而是为了提高资源使用效率来提高系统的效率。

多线程的优势:
1.提高界面程序的响应速度.
2.充分利用系统资源.

在线程编程中,继承Thread类或实现Runnable接口的类才具备多线程的能力。


线程的生命周期与主要的线程状态:
1. 新建状态(New).
2. 就绪状态(Runnable).
3. 运行状态(Run).
4. 阻塞状态(Block).
5. 终止状态(Dead).

线程的优先级用1~10表示,1表四优先级最高,默认值是5,每个优先级值对应Thread类中的一个公共静态常量。
如果有多个线程在等待,并不是优先级越高就肯定越早执行,只是获得的机会更多一些,因此通常情况下,不要依靠线程优先级来控制线程的状态。

线程调度
1. 线程睡眠sleep()
i. 调用sleep()方法使线程处于睡眠,线程由运行状态进入不可运行的状态,睡眠时间过后线程再次进入可运行状态。
2. 暂停线程yield()
i. 调用yield()方法可暂停当前线程执行,将CPU资源让出来,允许其他线程执行。
ii. Yield()的优点是保证有工作时不会让CPU闲置,主要用于编写多个合作线程,也适合于强制线程间的合作。
3. 连接线程join()
i. 调用join()方法可使当前线程暂停执行,等待调用该方法的线程的结束后再继续执行本线程。
4. 中断线程interrupt()
i. Interrupt()方法可为线程设置一个中断标记,以便于run()方法运行时使用isInterrupted()方法能够检测到。此时,线程在sleep()之类的方法中被阻塞时,由sleep()方法抛出一个InterruptException()异常,然后捕捉这个异常以处理超时。
ii. Interrupt()只是一个中断标记,并没有中断线程运行。

将线程标记为守护线程(后台线程):setDaemon(true); 注意该方法要在线程开启前使用。和前台线程一样开启,并抢资源运行,所不同的是,当前台线程都结束后,后台线程会自动结束。无论后台线程处于什么状态都会自动结束。

线程的同步
在多线程编程中,这种会被多个线程同时访问的资源叫做临界资源。

Synchronized关键字是一个修饰符,可以修饰方法或代码块。其作用是:对于同一个对象(不是一个类的不同对象),当多个线程都同时调用该方法或代码块时,必须一次执行,也就是说,如果两个或两个以上的线程同时执行该段代码,如果一个线程已经开始执行该段代码,则另外一个线程必须等待这个线程执行完这段代码才能开始执行。
多线程的同步提高了系统的安全问题

线程同步的两种表现形式:
1.同步代码块。

synchronzied(对象锁){
需要被同步的代码。(哪些需要同步哪些不需要一定要分清)
}

2.同步函数。

就是在函数上加了synchronzied关键字进行修饰。、
同步代码块可以使用任意对象作为锁。
同步函数使用的锁只有一个,就是this。
注意:static同步函数使用的锁是该函数所属类的对象。类名.class
售票系统中的线程同步方法:
package com.hbsi;
//模拟临界资源的类
class Tickets{
public int tickets;
public Tickets(){
tickets=10;
}
public synchronized void action(String name){
System.out.println(name+"抢到了第"+tickets+"号票");
tickets--;
}
}
//访问数据的线程
class TicketsThread extends Thread{
Tickets t;
String name;
public TicketsThread(Tickets t,String name){
this.t=t;
this.name=name;
start();
}
@Override
public void run() {
try {
for(int i=0;i<5;i++){
t.action(name);
Thread.sleep(20);
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

}
//测试多线程访问时的问题 
public class TestMulThread2{
public static void main(String[] args) {
// TODO Auto-generated method stub
Tickets t=new Tickets();
TicketsThread d1=new TicketsThread(t,"小王");
TicketsThread d2=new TicketsThread(t,"小张");
}
}
运行结果:
小王抢到了第10号票
小张抢到了第9号票
小王抢到了第8号票
小张抢到了第7号票
小王抢到了第6号票
小张抢到了第5号票
小王抢到了第4号票
小张抢到了第3号票
小王抢到了第2号票
小张抢到了第1号票

售票系统中的线程同步代码块:
package com.hbsi;


public class ticket1 implements Runnable{
private int ticket=100;
@Override
public void run() {
// TODO Auto-generated method stub
//Object obj=new Object();
while(true){
synchronized(this){
if(ticket>0){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"..."+ticket--);
}else{
break;
}
}
}

}
public static void main(String[] args) {
// TODO Auto-generated method stub
ticket1 t=new ticket1();
Thread td1=new Thread(t);
Thread td2=new Thread(t);
td1.start();
td2.start();
}
}

单例类懒汉式的线程同步:
Public class Single{
                  privatestatic Single s = null;
                  privateSingle(){}
                  publicstatic Single getInstance(){
                            if(s==null){
                                    synchronized(Single.class)
                                    {
                                              if(s==null)
                                                  s= new Single();
                                    }
                            }
                            return s;
                  }
        }
线程同步以后,懒汉式的安全性就进一步的提高。

线程的死锁:
产生死锁的原因主要是 
因为系统资源不足。 
进程运行推进的顺序不合适。 
资源分配不当等。 
如果系统资源充足,进程的资源请求都能够得到满足,死锁出现的可能性就很低,否则就会因争夺有限的资源而陷入死锁。其次,进程运行推进顺序与速度不同,也可能产生死锁。 

产生死锁的四个必要条件 
互斥条件:一个资源每次只能被一个进程使用。 
请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。 
不剥夺条件:进程已获得的资源,在末使用完之前,不能强行剥夺。 
循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。 
这四个条件是死锁的必要条件,只要系统发生死锁,这些条件必然成立,而只要上述条件之一不满足,就不会发生死锁。

线程间的通信
  两个或者两个以上的线程在处理同一个资源时,处理动作是不一样的。
  这时就需要将动作代码分别存放在不同的run方法,而run方法要封装单独的类中。
        示例:生产者,消费者。
-------------------------------------------------
        在同步中的使用的方法。
        wait,notify,notifyAll。这三个方式都定义Object类中。
        wait:让当前线程处于等待(冻结状态)状态。将该线程存入到了线程池中。
        notify:唤醒被等待的线程。通常唤醒的是线程池中的第一个。
        notifyAll:唤醒线程池中所有被等待线程。
        这些方法要用在同步中。并要明确三个方法所属的同步锁。
        synchronized(obj)
        {
                  obj.wait();
                  obj.notify()
        }
        在同步中无论被等待多少个线程,同时唤醒后,
        注意:只可能有一个线程会持有锁,并执行。其他线程即使子啊同步块中,也执行不了。
--------------------------------------------------- 
        wait(): 释放cpu的执行权。释放锁。
        sleep():释放cpu的执行权。不释放锁。


多线程在开发中的应用
1.下载
2.聊天

内部类中的多线程
public class ThreadDemo6 {

    /**
    * @param args
    */
    public static void main(String[] args) {
        
        new Thread(){
            public void run(){
                for(int i=0;i<100;i++){
                System.out.println("a="+i);
                }
            }
        }.start();
        
        for(int i=0;i<100;i++){
            System.out.println("b="+i);
        }
        
        Runnable r=new Runnable(){

            @Override
            public void run() {
                for(int i=0;i<100;i++){
                    System.out.println("c="+i);
                }
            }
            
        };
        new Thread(r).start();
    }
}

JDBC开发----数据库中大文本以及多媒体文件的插入读写
111307156 CSDNJava班 乔晓松
★★★
在开发中,需要把一些大文本或二进制的数据保存到数据库中,大数据称为lob,lob分2中:clob和blob;
★ clob:用于存储大文本,即text。
★ blob:用于存储二进制数据,即:图片,歌曲,二进制文件等数据。
★对MySQL而言只有blob,而没有clob,mysql存储大文本采用的是Text,Text和blob分别又分为:
TINYTEXT、TEXT、MEDIUMTEXT和LONGTEXT
TINYBLOB、BLOB、MEDIUMBLOB和LONGBLOB 
在建立表结构时大文本的数据类型就定义为:text,二进制数据就定义为:blob。

★ Text类型的调用此方法设置:
PreparedStatement.setCharacterStream(index, reader, length);
//注意length长度须设置,并且设置为int型
Text类型的获取方法:
reader = resultSet. getCharacterStream(i);

★ blob类型的调用此方法设置:
PreparedStatement. setBinaryStream(i, inputStream, length);
//注意length长度须设置,并且设置为int型
blob类型的获取方法:
InputStream in  = resultSet.getBinaryStream(i);

★ JDBC进行批处理
多处理多条sql语句时,建议采用JDBC的批处理机制,以提高执行效率。
实现批处理有2中方式:
第一种方法:Statement.addBatch(sql)  list
执行批处理语句
executeBatch()方法:执行批处理命令
clearBatch()方法:清除批处理命令

举例:
Connection conn = null;
Statement st = null;
ResultSet rs = null;
try {
conn = JdbcUtil.getConnection();
String sql1 = "insert into user(name,password,email,birthday) 
values('kkk','123','abc@sina.com','1978-08-08')";
String sql2 = "update user set password='123456' where id=3";
st = conn.createStatement();
st.addBatch(sql1);  //把SQL语句加入到批命令中
st.addBatch(sql2);  //把SQL语句加入到批命令中
st.executeBatch();
} finally{
JdbcUtil.free(conn, st, rs);
}

采用Statement.addBatch(sql)方式实现批处理:
★ 优点:可以向数据库发送多条不同的SQL语句。
★ 缺点:
SQL语句没有预编译。
当向数据库发送多条语句相同,但仅参数不同的SQL语句时,需重复写上很多条SQL语句。例如:
Insert into user(name,password) values(‘aa’,’111’);
Insert into user(name,password) values(‘bb’,’222’);

第二种方法:
PreparedStatement.addBatch()

举例:
package Demo;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileReader;
import java.sql.Connection;
import java.sql.PreparedStatement;
import Util.DBManager;
/**
* 利用批处理向数据库中插入大文本和图片
* @author 乔晓松
*
*/
public class Person {

/**
* @param args
*/
public void insert(){
Connection con=DBManager.getConnection();
PreparedStatement st=null;

String sql="insert into person(id,name,headimg,intro) values(?,?,?,?)";
try {
//执行sql语句
st=con.prepareStatement(sql);
//批处理语句
String[] name={"aa","bb","cc"}; 
String[] img={"src/Demo/1.gif","src/Demo/2.gif","src/Demo/3.gif"};
String[] text={"src/Dao/Demo1.java","src/Demo/Test.java","src/Util/DBManager.java"};
//利用for循环赋值
for(int i=1;i<=3;i++){
st.setInt(1, i);
st.setString(2, name[i-1]);
File f1=new File(img[i-1]);
FileInputStream fis=new FileInputStream(f1);
st.setBinaryStream(3, fis, f1.length());

File f2=new File(text[i-1]);
BufferedReader br=new BufferedReader(new FileReader(f2));
st.setCharacterStream(4, br, f2.length());
//添加到批处理
st.addBatch();
}
//执行批处理
int[] x=st.executeBatch();
if(x.length==3){
System.out.print("插入成功!!!");
}
} catch (Exception e) {
e.printStackTrace();
}finally{
//关闭资源
DBManager.dbClose1(st, con);
}
}
// 主方法
public static void main(String[] args) {
//创建对象
Person p=new Person();
//执行insert方法,出入数据 
p.insert();
}

}

采用PreparedStatement.addBatch()实现批处理
★ 优点:发送的是预编译后的SQL语句,执行效率高。
★ 缺点:只能应用在SQL语句相同,但参数不同的批处理中。因此此种形式的批处理经常用于在同一个表中批量插入数据,或批量更新表的数据。

JDBC—存储过程以及事务处理
存储过程的参考写法:
delimiter

createproceduremyproc(inuidchar(8),outunamechar(20))beginselectnameintounamefromtestwhereid=uid;end

delimiter ;
调用存储过程:
call myproc(id,@name);
查看参数2:select @name;

JDBC调用存储过程
CallableStatement cs = conn.prepareCall("{call myproc(?, ?)}");
设置参数
cs.setString(1, id); //设置第一个参数
cs.registerOutParameter(2, Types.VARCHAR); //设置第二个参数的参数类型
cs.execute(); //执行语句
System.out.println(cStmt.getString(2)); //输出第二个参数

事务的概念
事务指逻辑上的一组操作,组成这组操作的各个单元,要不全部成功,要不全部不成功。
设置事务回滚点
• Savepoint sp = conn.setSavepoint();
• Conn.rollback(sp);
• Conn.commit();  //回滚后必须要提交

创建JDBC事务的步骤如下:
1. 将事务的提交方式设置为非自动提交
i. con.setAutoCommit(false);

2. 将需要添加事务的代码放入try,catch块中
3. 在try块内添加事务的提交操作,表示操作无异常,提交事务。 
    conn.commit();
4.在catch块内添加回滚事务,表示操作出现异常,撤销事务:
    conn.rollback();
5.设置事务提交方式为自动提交:
    conn.setAutoCommit(true);

事务的特性:
原子性
一致性
隔离性
持久性
事务的隔离性
脏读:指一个事务读取了另外一个事务未提交的数据
不可重复读:在一个事务内读取表中的某一行数据,多次读取结果不同
虚读(幻读):是指在一个事务内读取到了别的事务插入的数据,导致前后读取不一致

事务隔离性的设置语句
数据库共定义了四种隔离级别:
• Serializable:可避免脏读、不可重复读、虚读情况的发生。(串行化)(序列化)
• Repeatable read:可避免脏读、不可重复读情况的发生。(可重复读)
• Read committed:可避免脏读情况发生(读已提交)。
• Read uncommitted:最低级别,以上情况均无法保证。(读未提交)
set  transaction isolation level 设置事务隔离级别
select @@tx_isolation 查询当前事务隔离级别


JDBC的开发过程:

1.      首先建立数据库,插入表的记录,新建一个Java项目,在项目下建立lib文件,并把MySQL驱动导入到Java项目中lib文件中。

2.      编写代码,并把mysql驱动加载到Java项目中,构建路径

推荐方法:class.froName(“com.mysql.jdbc.Driver”);

3.      建立连接

String url=”jdbc:mysql://localhost:3306/xsgl”:

String user=”root”:

Sting pass=”root”:

Connectioncon=DriverManager.getConnection(url,user,pass);

4.      创建Statement对象

Statementst=con.createStatement();

5.      执行

ResultSetrs=st.excuteQuery(sql);

6.      遍历结果集

while(rs.next()){

}

7.      关闭资源

rs.close();

st.close();

con.close()

注意:关闭资源之前,必须判断rs,st,con是否为空,如果为空就不需要关闭,否则关闭资源。//if(rs!=null || st!=null ||con!=null){

                      //关闭资源

                             rs.close();

st.close();

con.close()

}//if尽可能的写在finally中,确保资源的释放

Connection对象是非常稀有的资源,用完后必须马上释放,如果Connection不能及时、正确的关闭,极易导致系统宕机。Connection的使用原则是尽量晚创建,尽量早的释放。

为了确保资源的释放,尽量把资源释放代码放到finally语句块中。

 

Connection对象常用的方法有:

•        createStatement():创建向数据库发送sql的statement对象。

•        prepareStatement(sql) :创建向数据库发送预编译sql的PrepareSatement对象。

•        prepareCall(sql):创建执行存储过程的callableStatement对象。

•        setAutoCommit(boolean autoCommit):设置事务是否自动提交。

•        commit() :在链接上提交事务。

•        rollback() :在此链接上回滚事务。

Statement对象常用方法:

•        execute(String sql):用于向数据库发送任意sql语句

•        executeQuery(String sql):只能向数据发送查询语句。

•        executeUpdate(String sql):只能向数据库发送insertupdatedelete语句

•        addBatch(String sql) :把多条sql语句放到一个批处理中。

•        executeBatch():向数据库发送一批sql语句执行。

ResultSet对象常用的结果集进行滚动的方法:

•        next():移动到下一行

•        Previous():移动到前一行

•        absolute(int row):移动到指定行

•        beforeFirst():移动resultSet的最前面。

•        afterLast() :移动到resultSet的最后面。

提取代码到配置文件中,文件名.properties

在实际开发中为了避免数据库改动,需要把一些必要的代码写到一个单独的配置文件中,这就简化了对大量代码的改动:如

        在驱动连接数据库时,String url=”jdbc:mysql://localhost:3306/xsgl”:

String user=”root”:

Sting pass=”root”:

像这些代码都可以提取到配置文件中,在配置文件中就可以写为user=root

在写代码需要使用配置文件的内容时,

InputStream in=DBManager.class.getClassLoader().getResourceAsStream("db.properties");

Properties pro=new Properties();

try {

           pro.load(in);

       } catch (IOException e) {

           // TODO Auto-generated catch block

           e.printStackTrace();

       }

       driver=pro.getProperty("driver");

       url=pro.getProperty("url");

       user=pro.getProperty("user");

       password=pro.getProperty("password");

}catch(Exceptione){

}

通过输入流就可以读取获取到配置文件的内容,附加给创建的成员变量,并加以使用

当系统运行时,需要读取一下配置文件,以获取配置文件的内容


统计某字符串中某子串出现的次数

class StringDemo1
{
public static void main(String[] args) {
int n = getString("abcdnfgabchedabckkfdnabct","abc");
System.out.println("字符串出现的次数为:"+n);
}
public static int getString(String str,String str1){
   int count=0;
int index=0;
while(true){
index = str.indexOf(str1,index);
if(index==-1){
break;
}
index = index + str1.length();
count++;
}
return count;
}
}


indexOf(String.indexOf 方法)

字符串的IndexOf()方法搜索在该字符串上是否出现了作为参数传递的字符串,如果找到字符串,则返回字符的起始位置 (0表示第一个字符,1表示第二个字符依此类推)如果说没有找到则返回 -1 
返回 String 对象内第一次出现子字符串的字符位置。
[code=csharp]public indexOf(value:String, [startIndex:Number]) : Number[/code]
搜索字符串,并返回在调用字符串内 startIndex 位置上或之后找到的 value 的第一个匹配项的位置。此索引从零开始,这意味着字符串中的第一个字符被视为位于索引 0 而不是索引 1 处。如果未找到 value,该方法会返回 -1。
参数value:String - 一个字符串;要搜索的子字符串。
startIndex:Number [可选] - 一个整数,指定搜索的开始索引。
返回Number - 指定子字符串的第一个匹配项的位置,或 -1。
--------------------------------------------------------------------------------------------------------------------------------------------------
indexOf 方法 
返回 String 对象内第一次出现子字符串的字符位置。

strObj.indexOf(subString[, startIndex])

参数 
strObj 
必选项。String 对象或文字。 
subString 
必选项。要在 String 对象中查找的子字符串。 
starIndex 
可选项。该整数值指出在 String 对象内开始查找的索引。如果省略,则从字符串的开始处查找。 
说明 
indexOf 方法返回一个整数值,指出 String 对象内子字符串的开始位置。如果没有找到子字符串,则返回 -1。 
如果 startindex 是负数,则 startindex 被当作零。如果它比最大的字符位置索引还大,则它被当作最大的可能索引。 
从左向右执行查找。否则,该方法与 lastIndexOf 相同。 
示例 
下面的示例说明了 indexOf 方法的用法。

function IndexDemo(str2){var str1 = "BABEBIBOBUBABEBIBOBU"var s = str1.indexOf(str2);return(s);}

实例:
我获得一个字符串a为 "1,18,33" 
如果写成 a indexOf("1") 好象查不出来 更重要的是 18和1前面都有个1所以成立的条件不准确 请问应该怎么写啊

indexOf这样用

复制代码
string test = "1,18,33";if (test.IndexOf("1") > -1){     Response.Write("存在");}else{     Response.Write("不存在");}
复制代码

但是如果说只有1符合要求,而18中的1不符合要求,那不能用IndexOf来做,这样

复制代码
using System.Text.RegularExpressions;string test = "1,18,33";if (Regex .IsMatch(test, @"\b1\b")){     Response.Write("存在");}else{     Response.Write("不存在");}
复制代码

注释:
\b 在正则中匹配一个单词边界
写了一个方法

复制代码
//src 源字符串//tar 待比较字符串private bool CheckString(string src, string tar){     string temp = Regex.Replace(tar, @"[.$^{\[(|)*+?\\]", "");     if (temp.Length < tar.Length)         return false;     if (Regex.IsMatch(src, @"\b" + tar + @"\b"))         return true;     return false;}


原创粉丝点击