lqxue

常用链接

统计

book

tools

最新评论

2008年7月4日 #

如何在 Windows 中删除 ActiveX 控件

删除 ActiveX 控件,请按照相应部分中的步骤操作。

Internet Explorer 3.0、3.01 和 3.02

  1. 单击“开始”,指向“设置”,单击“控制面板”,双击“添加/删除程序”,然后单击“安装/卸载”选项卡。
  2. 如果您要删除的 ActiveX 控件出现在安装的程序列表中,请单击该 ActiveX 控件,单击“添加/删除”,然后按照屏幕上的说明操作。如果该 ActiveX 控件没有出现在安装的程序列表中,则继续执行下一步。
  3. 单击“开始”,单击“运行”,在“打开”框中键入下列行,然后单击“确定”:
    regsvr32 drive:\windows\occache\filename.ocx /u
    注意drive 是 Windows 文件夹所在的驱动器号,windows 是安装 Windows 的文件夹名,而 filename.ocx 是您想要删除的 ActiveX 控件。

    注意:如果您不知道要删除的 ActiveX 控件 (.ocx) 的文件名,则可以通过查看安装或使用 ActiveX 控件的网页的超文本标记语言 (HTML) 源文件来确定该文件名。要查看一个网页的 HTML 源文件,请右键单击该网页的空白区域,然后单击“查看源文件”。
  4. 在 Windows 资源管理器或 Windows NT 资源管理器中,单击 Windows\Occache 文件夹中的 .ocx 文件,然后单击“文件”菜单上的“删除”。

Occache 是在 Internet Explorer 3.x 的所有版本中安装有 ActiveX 控件的文件夹的名称。Regsvr32.exe 文件是由 Internet Explorer 安装的,并且可用于注册和删除 ActiveX 控件的注册表项。

Internet Explorer 4.x 或更高版本(所有平台)

Internet Explorer 4.x 或更高版本,包括 Occache.dll 文件,该文件可用于使用“shell 文件夹”枚举、更新和安全地卸载 ActiveX 控件。

  1. 单击“开始”,指向“设置”,单击“控制面板”,双击“添加/删除程序”,然后单击“安装/卸载”选项卡。
  2. 如果您要删除的 ActiveX 控件出现在安装的程序列表中,请单击该 ActiveX 控件,单击“添加/删除”,然后按照屏幕上的说明操作。如果该 ActiveX 控件没有出现在安装的程序列表中,则继续执行下一步。
  3. 在 Windows 资源管理器或 Windows NT 资源管理器中,双击 Windows\Downloaded Program Files 文件夹或 Winnt\Downloaded Program Files 文件夹,右键单击您想要删除的 ActiveX 控件,然后单击“删除”。
  4. 在系统提示您是否删除该 ActiveX 控件后,单击“是”。

重要说明:如果您运行的是 Internet Explorer 4.0,则不应删除以下 ActiveX 控件:

  • DirectAnimation Java Classes
  • Internet Explorer Classes for Java
  • Microsoft XML Parser for Java
  • Win32 Classes

Internet Explorer 5.0 或更高版本不要求 Downloaded Program Files 文件中的这些组件。

删除 ActiveX 控件时出现的错误消息

在您尝试使用 Occache shell 文件夹删除一个 ActiveX 控件时,可能显示以下错误消息之一:

  • 共享冲突 这些程序文件当前正由一个或多个程序使用。请关闭一些程序,然后重试。您可能需要重新启动 Windows。
  • 组件删除 即将删除 Windows 系统 DLL:(<path\filename>)。是否删除?

共享冲突:

如果您要尝试删除的 ActiveX 控件当前在内存中由 Internet Explorer 或“活动桌面”组件加载,则显示此错误消息。

要解决此错误消息,请按照下列步骤操作:

  1. 关闭所有打开的 Internet Explorer 窗口。
  2. 禁用“活动桌面”。为此,请右键单击桌面上的空白区域,指向“活动桌面”,然后单击“查看网页”以清除该复选标记。
  3. 按照本文中前面部分的“Internet Explorer 4.0 或更高版本”部分中介绍的步骤,删除该 ActiveX 控件。

    注意:您最好在删除 ActiveX 控件前重新启动 Windows。

组件删除:

仅当您要删除的 ActiveX 控件向已注册的 Occache 文件夹以外的文件夹(例如,Windows\System 或 Winnt\System32)安装文件时,该消息才出现在 4.01 Service Pack 1 (SP1) 之前的 Internet Explorer 4 版本中。Occache 不是总能确定这些文件是否正由其程序共享。

如果您确定消息中显示的一个或多个文件未由 Windows 或其他程序使用,请单击“是”。否则,单击“否”。

注意:在 Internet Explorer 4.01 SP1 和更高版本中,Occache 不删除(或提示您删除)注册的 Occache 文件夹之外的相关文件。

支持多个 Occache 文件夹

Internet Explorer 4.0 和更高版本支持多个 Occache 文件夹。Occache 文件夹的列表位于以下注册表项中:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings\ActiveX Cache

默认情况下,Internet Explorer 4.0 和更高版本使用 Windows\Downloaded Program Files 或 Winnt\Downloaded Program Files 文件夹。如果是从 Internet Explorer 3.x 升级的,则 Occache 和 Downloaded Program Files 文件夹可能都存在。在此情况下,所有新的 ActiveX 控件都安装在 Downloaded Program Files 文件夹中,但以前安装的 ActiveX 控件仍在 Occache 文件夹中工作。当您在 Windows 资源管理器、Windows NT 资源管理器或“我的电脑”中打开 Occache 或 Downloaded Program Files 文件夹时,将显示所有 ActiveX 控件,而与该 ActiveX 控件的文件所在的文件夹无关。在此情况下,注册表项中将出现以下字符串值:

"0"="C:\\WINDOWS\\OCCACHE"
"1"="C:\\WINDOWS\\Downloaded Program Files"

有关 ActiveX 控件的其他信息,请参见 Microsoft 知识库中的以下文章:

154544  (http://support.microsoft.com/kb/154544/LN/ ) ActiveX 技术说明

有关 Internet Explorer 在发生冲突(例如,如果文件已存在)时如何下载 ActiveX 控件的信息,请参见 Microsoft 知识库中的以下文章:

196150  (http://support.microsoft.com/kb/196150/LN/ ) INFO:为什么会在代码下载期间创建 CONFLICT 目录

posted @ 2010-06-08 16:16 lqx 阅读(582) | 评论 (0)编辑 收藏

A very cool PDF to Word converter.

a  very cool pdf to word converter:http://www.pdftoword.com

posted @ 2010-03-31 16:29 lqx 阅读(227) | 评论 (0)编辑 收藏

html 导出excel

     摘要:     <head>    <body>   <table class="dataintable" id='table22'>         <tbody><tr> &nb...  阅读全文

posted @ 2010-03-21 09:42 lqx 阅读(321) | 评论 (0)编辑 收藏

java 程序转换成exe程序

http://www.ej-technologies.com/products/exe4j/overview.html

posted @ 2010-03-21 09:37 lqx 阅读(258) | 评论 (2)编辑 收藏

退出诺顿命令

在运行里执行: smc -stop

posted @ 2010-03-18 16:57 lqx 阅读(309) | 评论 (0)编辑 收藏

无提示框关闭浏览器

window.open(....);
this.focus();  self.opener = this;  self.close();

posted @ 2010-03-15 14:36 lqx 阅读(224) | 评论 (0)编辑 收藏

IE foolscreen/全屏 浏览页面

There are two javascript ways to view web site in full screen mode in IE:

1. window.open('http://www.sina.com.cn','','fullscreen')
   Note: If view the page remotely, this way will ineffective, and you can use the second one instead.
 

2. var wsh=new ActiveXObject("wscript.shell");
   wsh.run("iexplore -k http://www.google.com");
 

posted @ 2010-03-15 14:22 lqx 阅读(205) | 评论 (0)编辑 收藏

IE7: Automation server can't create object javascript

问题描述:使用ie6导出excel表正常,但是在IE7 下总是报错:“ Automation server can't create object javascript”。
 
1. In Internet Explorer > Tools > Internet Options > Security > Custom Level
2. Enabling or prompting "Initializing and Script Activex controls not marked as safe"



3.IE7对环境的设置特别严格,常用到的有两部分,一个是安全里面的“internet”设置,一个是“信任站点”的设置。

  1>需要把站点加入信任站点列表;
  2>设置“信任站点”项的“自定义级别”,启用“对未标记为可安全执行 ActiveX控件初始化并执行脚本”即可。

posted @ 2010-03-15 14:14 lqx 阅读(596) | 评论 (0)编辑 收藏

Accecing a field on a tab navigator

Default Accecing a field on a tab navigator

hi,


i have a tab navigator. in one of my functions i'm trying to reference a field which is located on the second tab.

If i click "ok" from the first tab, which calls the function, which references the field on a second tab, it gives me a runtime error. But if i click on the second tab, and go back to the first, and then click on "OK" it works.

What is going on? am i supposed to somehow declare taht field before referencing it? to make it active..?

any help greatly appreciated.

Thanks!


this is the error i'm getting:

TypeError: Error #1009: Cannot access a property or method of a null object reference.
MadamZuZu is offline   Reply With Quote
  #2

 
 
 
Default

The children of a TabNavigator aren't created until they're needed. In your case, only the contents of the first tab are actually created, because they're part of what's needed when the TabNavigator is first displayed. The contents of the second tab won't be instantiated until they need to be displayed, which is when the second tab is clicked on. That's why that error is being thrown until you click on the second tab. This process of only instantiating components as they are needed is called deferred instantiation.

To force the contents of the other tabs to be instantiated, try changing the creationPolicy property of the TabNavigator to be "all". This will cause all of the different tabs to be instantiated, regardless of having been clicked on.

In the Flex docs, check out Container.creationPolicy for more details.

ActionScript Code:
            
<mx:TabNavigator creationPolicy="all">

posted @ 2010-03-14 11:34 lqx 阅读(256) | 评论 (0)编辑 收藏

用javascript操控css

W3C DOM Compatibility - CSS
From: http://www.quirksmode.org/dom/w3c_css.html#access


posted @ 2010-03-12 10:58 lqx 阅读(255) | 评论 (0)编辑 收藏

CSS 控制打印

From:http://martybugs.net/articles/print.cgi

Web Page Printability With CSS
author: Martin "mpot" Pot
date: 7 January 2005


Introduction

This article describes how to use CSS media types to make your website much more printer-friendly. An overview of CSS media types is given, and sample HTML and CSS code is provided, detailing how to implement CSS media types for improving printability.

Why?

Most webpages do not print very well, with large amounts of the printed page being wasted with banners, navigation menus, advertising, and other unnecessary content. When attempting to print out the main text of a webpage, you often have to resort to copying the text into Word or another editor, and then printing it.

Some websites make use of a link at the bottom of the page, linking to a "printable version" of the same page. However, this requires additional effort on the part of the web developer.

There is a much easier way to make your pages print better, and that's via the use of CSS media types.

For example, all content on MartyBugs.Net has been designed to be printer-friendly. When printing pages from this site using a modern browser, elements such as the left menu column and the right column (where used) will be hidden, thus ensuring there's more room on the printed page for the main content.

page viewed on screen
page as displayed on a 1024x768 screen

The image above shows how one of the pages on this website would be displayed on a computer screen, at a resolution of 1024x768.

printed page
printed page, optimised with CSS media types
printed page,
no print optimisation

printed page,
optimised for printing

The left image above shows how the same page will look when printed, if all the page content is printed. Notice how little room there is in the centre of the page for the main content.

The right image above shows the same page, but the navigation and other content on the left and right hand sides of the page is not printed. CSS media types have been used to hide this content when the page is printed.

CSS Media Types

The primary aim of the CSS media types is to allow the web-page author to define different styles for a page, depending on the media being used to display the page. CSS 2.1 supports numerous media types, including all (suitable for all devices), screen (computer screens), print (pages viewed on-screen in print-preview mode and printed pages).
Other less-common media types are also supported, such as braille, embossed, handheld, projection, speech, etc, but we won't be discussing any of these.

CSS media types are defined using the rule in your CSS style-sheet, or in your in-line CSS style definitions. For example, to define different font sizes for the print and screen media types, as well as a common line-height to be used for both, the CSS definition is as follows:

  @media print {
body { font-size: 10pt }
}
@media screen {
body { font-size: 13px }
}
@media screen, print {
body { line-height: 1.2 }
}

The CSS media types allow you to specify different CSS properties for any element, so it will be displayed differently on the screen than when printed. For the purposes of this article, the only thing we're interested in is to hide some page elements when the page is printed.

Refer to the W3C CSS 2.1 Media Definitions for more details on CSS media types.

Using CSS Media Types

The web pages on this website are all generated on-the-fly, using server-side Perl templates. All pages have a number of common elements, namely:
  • a banner across the top
  • navigation menu on the left side
  • main content in the centre
  • advertising and other content on the right side
  • footer across the bottom
When someone prints out a page from this website, CSS media types are used to hide a number of elements on the page, including the navigation menu, advertising, and the navigation content in the footer.

To provide a working demonstration of how CSS media types can be used in this way, a demonstration web page was coded, using tables to define the banner area across the top of the page, with a column down the left-hand side for the navigation menu, a column down the right-hand side for other content, and a footer across the bottom of the page.

This layout is one of the most commonly used page layouts on the internet at the present - hence my choice to use it as an example.

the example page
the example page

Firstly, we define the CSS styles for the page:

  <style type="text/css">
@media print {
.noprint { display: none; }
}

</style>

Note that the CSS styles can also be defined using a separate CSS file, but example page has the CSS defined in-line for simplicity (and to keep the example to a single file).

The above CSS definition is defining a style called noprint, and will only be applied to printed content. Setting the display property to none means any content using this CSS style will not be displayed when printed, but will be displayed for all other media types.

There are a number of components on this page that we don't want printed, namely the columns on the left-hand side and on the right-hand side. The noprint style is applied to the table cells holding this content, thus ensuring they won't be visible when the page is printed.

<table border='1' cellpadding='4' cellspacing='0' width='100%' >
<tr height='60'><td colspan='3'>
banner place-holder
</td></tr>
<tr><td width='150' valign='top' class='noprint'>
left-side content place-holder
</td><td>
<b>main content</b>
[snip!]
</td><td width='150' valign='top' class='noprint'>
right-side content place-holder
</td></tr><tr><td colspan='3'>
footer content place-holder
</td></tr>
</table>

This will result in the columns on the left and right-hand sides being hidden when the page is printed, thus providing more space on the printed page for the content itself.

Note that this style needs to be applied to the table cells themselves, and not just to the content in these table cells, else the (empty) cells will still show up on the printed copy.

Testing Your CSS

The easiest way to test CSS styles for print media is to use a web browser which has print preview capabilities. The print preview will give you a fairly accurate representation of how the page will look when it is printed, and is a much more efficient way to test your media styles, rather than actually printing out pages on a printer.

Most popular web browsers should support print preview functionality. The FireFox browser has print preview functionality, although it lacks any zoom/unzoom capabilities.

As an alternative to using print preview, you can print the web page to a PDF file. There are numerous (costly, freeware, and anywhere in between) software packages for doing this. I recommend using the freeware and open-source PDFCreator, which is a Windows printer driver which allows you to create PDFs from any Windows application, just by selecting the PDFCreator driver as the virtual printer from that application.

Also be sure to use the W3C's free CSS Validation Service to check your CSS definitions.

References


posted @ 2010-03-12 10:55 lqx 阅读(544) | 评论 (0)编辑 收藏

MS09-073: Description of the security update for Windows XP, Windows 2000, and Windows Server 2003: December 8, 2009

http://support.microsoft.com/kb/973904

Let me fix it myself

To unregister the mswrd632 converter yourself, edit the registry as follows:
  1. Click Start, click Run, type regedit, and then click OK.
  2. Locate and then click the following registry subkey:
    • For 32-bit versions of Windows:
      HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Shared Tools\Text Converters\Import\MSWord6.wpc
    • For 64-bit versions of Windows:
      HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Shared Tools\Text Converters\Import\MSWord6.wpc
  3. On the Edit menu, click Delete.
  4. Click Yes.
  5. Exit Registry Editor.
This change will effectively unregister the converter and disable it for third-party applications and for Microsoft Office. Microsoft Office will use its own text converters to open these kinds of files.

posted @ 2010-03-04 01:56 lqx 阅读(165) | 评论 (0)编辑 收藏

Fix “Word Cannot Start the Converter MSWRD632.WPC” Error

The user was running Office 2007 and getting this error. After doing some research, we came across a few possible solutions. In this post, I’ll list them out here.

Method 1 – Unregister Text Converter

Basically, in Windows XP SP2 and above and Windows Server 2003 SP1 and above, if you have a plain text file or another kind of file that is not a Microsoft Word file, but has a .doc extension, you will get this error.

This can also happen if you are opening a really old document created by Word for Windows 6.0 or Word 97 documents. In this case, you can disable the mswrd632 converter so you don’t get this error. The files will then be opened by the Microsoft Office text converters.

You can unregister this converter by going to Start, then run and typing regedit. Then navigate to the following key:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Shared Tools\Text Converters\Import\MSWord6.wpc

mswrd632 error word

Right-click on the MSWord6.wpc key in the left hand pane and choose Delete. If you have a Word 97 document, you should still be able to open it in Word 2003 or 2007. However, you will not be able to open these files in WordPad anymore. You’ll get an error like:

Cannot load Word for Windows 6.0 files

If you really have to use WordPad to open Word 6.0/95 files, you can re-enable the Word 6.0/95 for Windows and Macintosh to RFT converter. Open the registry and go to the following keys:

For 32-bit versions of Windows

HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\ Applets\Wordpad

For Microsoft Windows on Windows 64 (WOW) mode

HKEY_LOCAL_MACHINE\Software\Wow6432Node\Microsoft\Windows\ CurrentVersion\Applets\Wordpad

If the Wordpad key is not there in the left-hand pane, create it. After that, create a new DWORD value in the right-pane called AllowConversion and give it a value of 1.

Method 2 – Copy the MSWrd632.wpc File

The other way to solve this issue is to copy the MSWrd632.wpc file from another computer to the computer having problems.

The only issue with this is that it is less secure and makes your computer vulnerable to a possible security hack, so don’t do this unless you really have to or that computer is not connected to the Internet.

You can usually find this file in the following path:

C:\Program Files\Common Files\Microsoft Shared\TextConv\

That’s about it! If you are still having this problem, post a comment here and I’ll try to help! Enjoy!

posted @ 2010-03-04 01:53 lqx 阅读(3325) | 评论 (2)编辑 收藏

COM Add In

详解COM Add InLoadBehavior及其妙用
http://blog.csdn.net/v_jzho/archive/2007/10/06/1813080.aspx

基于Visual Studio 2003/2005的Office插件开发FAQ
http://blog.csdn.net/tonyqus/archive/2007/02/24/1513256.aspx

posted @ 2010-03-03 14:58 lqx 阅读(140) | 评论 (0)编辑 收藏

Deploy Assembly in GAC

There are several ways to deploy an assembly into the global assembly
cache:

1) Use an installer designed to work with the global assembly cache. This
is the preferred option for installing assemblies into the global assembly
cache

2) Use a developer tool called the Global Assembly Cache tool (Gacutil.exe)
provided by the .NET Framework SDK.

3) Use Windows Explorer to drag and drop assemblies into the cache.

4) use install shield. (注意:installshield里只有msi等几个类型的项目支持这个)

From:http://bytes.com/topic/net/answers/109942-deploy-assembly-gac

posted @ 2010-03-03 10:12 lqx 阅读(154) | 评论 (0)编辑 收藏

2007 Microsoft Office System Update: Redistributable Primary Interop Assemblies

http://www.microsoft.com/downloads/details.aspx?familyid=59DAEBAA-BED4-4282-A28C-B864D8BFA513&displaylang=en
http://msdn.microsoft.com/en-us/library/15s06t57(VS.80).aspx

posted @ 2010-03-02 17:01 lqx 阅读(732) | 评论 (1)编辑 收藏

error -7104: The destination of the component AllOtherFiles

The 'AllOtherFiles' is an entry automatically created when you check the GlobalAssemblyCache predefined folder. After you add in your file(s), perform the following steps:

1. Right-click "Destination Computer"
2. Check "Show Components"
3. Expand the [GlobalAssemblyCache] tree.
4. Delete the "AllOtherFiles" entry.

posted @ 2010-03-02 14:22 lqx 阅读(218) | 评论 (0)编辑 收藏

正则表达式(regular expression)

正则表达式(regular expression)

关键字: 正则表达式,Regular Expression

作者:笑容

发表于:2004年05月03日
最后更新:2005年01月17日 19:54
版权声明:使用
创作公用版权协议

引用地址:<a href="http://oo8h.51.net/docs/regular_expression.htm">正则表达式(regular expression)</a>

NAV: 笑容的八小时外 / 笑容的八小时外资料索引

如何创建一个网站 (HOW TO: Initiate a website) Red Hat Enterprise Linux 介绍


前言

正则表达式是烦琐的,但是强大的,学会之后的应用会让你除了提高效率外,会给你带来绝对的成就感。只要认真去阅读这些资料,加上应用的时候进行一定的参考,掌握正则表达式不是问题。

索引

1._引子
2._正则表达式的历史
3._正则表达式定义

3.1_普通字符
3.2_非打印字符
3.3_特殊字符
3.4_限定符
3.5_定位符
3.6_选择
3.7_后向引用

4._各种操作符的运算优先级
5._全部符号解释
6._部分例子
7._正则表达式匹配规则

7.1_基本模式匹配
7.2_字符簇
7.3_确定重复出现


1. 引子

  目前,正则表达式已经在很多软件中得到广泛的应用,包括*nix(Linux, Unix等),HP等操作系统,PHP,C#,Java等开发环境,以及很多的应用软件中,都可以看到正则表达式的影子。

  正则表达式的使用,可以通过简单的办法来实现强大的功能。为了简单有效而又不失强大,造成了正则表达式代码的难度较大,学习起来也不是很容易,所以需要付出一些努力才行,入门之后参照一定的参考,使用起来还是比较简单有效的。

例子: ^.+@.+""..+$

  这样的代码曾经多次把我自己给吓退过。可能很多人也是被这样的代码给吓跑的吧。继续阅读本文将让你也可以自由应用这样的代码。

  注意:这里的第7部分跟前面的内容看起来似乎有些重复,目的是把前面表格里的部分重新描述了一次,目的是让这些内容更容易理解。

2. 正则表达式的历史

  正则表达式的“祖先”可以一直上溯至对人类神经系统如何工作的早期研究。Warren McCulloch 和 Walter Pitts 这两位神经生理学家研究出一种数学方式来描述这些神经网络。

  1956 年, 一位叫 Stephen Kleene 的数学家在 McCulloch 和 Pitts 早期工作的基础上,发表了一篇标题为“神经网事件的表示法”的论文,引入了正则表达式的概念。正则表达式就是用来描述他称为“正则集的代数”的表达式,因此采用“正则表达式”这个术语。

  随后,发现可以将这一工作应用于使用 Ken Thompson 的计算搜索算法的一些早期研究,Ken Thompson 是 Unix 的主要发明人。正则表达式的第一个实用应用程序就是 Unix 中的 qed 编辑器。

  如他们所说,剩下的就是众所周知的历史了。从那时起直至现在正则表达式都是基于文本的编辑器和搜索工具中的一个重要部分。

3. 正则表达式定义

  正则表达式(regular expression)描述了一种字符串匹配的模式,可以用来检查一个串是否含有某种子串、将匹配的子串做替换或者从某个串中取出符合某个条件的子串等。

  • 列目录时, dir *.txt或ls *.txt中的*.txt就是一个正则表达式,因为这里*与正则式的*的含义是不同的。

  正则表达式是由普通字符(例如字符 a 到 z)以及特殊字符(称为元字符)组成的文字模式。正则表达式作为一个模板,将某个字符模式与所搜索的字符串进行匹配。

3.1 普通字符

  由所有那些未显式指定为元字符的打印和非打印字符组成。这包括所有的大写和小写字母字符,所有数字,所有标点符号以及一些符号。

3.2 非打印字符

字符 含义
"cx 匹配由x指明的控制字符。例如, "cM 匹配一个 Control-M 或回车符。x 的值必须为 A-Z 或 a-z 之一。否则,将 c 视为一个原义的 'c' 字符。
"f 匹配一个换页符。等价于 "x0c 和 "cL。
"n 匹配一个换行符。等价于 "x0a 和 "cJ。
"r 匹配一个回车符。等价于 "x0d 和 "cM。
"s 匹配任何空白字符,包括空格、制表符、换页符等等。等价于 [ "f"n"r"t"v]。
"S 匹配任何非空白字符。等价于 [^ "f"n"r"t"v]。
"t 匹配一个制表符。等价于 "x09 和 "cI。
"v 匹配一个垂直制表符。等价于 "x0b 和 "cK。

3.3 特殊字符

所谓特殊字符,就是一些有特殊含义的字符,如上面说的"*.txt"中的*,简单的说就是表示任何字符串的意思。如果要查找文件名中有*的文件,则需要对*进行转义,即在其前加一个"。ls "*.txt。正则表达式有以下特殊字符。
特别字符 说明
$ 匹配输入字符串的结尾位置。如果设置了 RegExp 对象的 Multiline 属性,则 $ 也匹配 '"n' 或 '"r'。要匹配 $ 字符本身,请使用 "$。
( ) 标记一个子表达式的开始和结束位置。子表达式可以获取供以后使用。要匹配这些字符,请使用 "( 和 ")。
* 匹配前面的子表达式零次或多次。要匹配 * 字符,请使用 "*。
+ 匹配前面的子表达式一次或多次。要匹配 + 字符,请使用 "+。
. 匹配除换行符 "n之外的任何单字符。要匹配 .,请使用 "。
[ 标记一个中括号表达式的开始。要匹配 [,请使用 "[。
? 匹配前面的子表达式零次或一次,或指明一个非贪婪限定符。要匹配 ? 字符,请使用 "?。
" 将下一个字符标记为或特殊字符、或原义字符、或向后引用、或八进制转义符。例如, 'n' 匹配字符 'n'。'"n' 匹配换行符。序列 '""' 匹配 """,而 '"(' 则匹配 "("。
^ 匹配输入字符串的开始位置,除非在方括号表达式中使用,此时它表示不接受该字符集合。要匹配 ^ 字符本身,请使用 "^。
{ 标记限定符表达式的开始。要匹配 {,请使用 "{。
| 指明两项之间的一个选择。要匹配 |,请使用 "|。
  •   构造正则表达式的方法和创建数学表达式的方法一样。也就是用多种元字符与操作符将小的表达式结合在一起来创建更大的表达式。正则表达式的组件可以是单个的字符、字符集合、字符范围、字符间的选择或者所有这些组件的任意组合。

3.4 限定符

限定符用来指定正则表达式的一个给定组件必须要出现多少次才能满足匹配。有*或+或?或{n}或{n,}或{n,m}共6种。
*、+和?限定符都是贪婪的,因为它们会尽可能多的匹配文字,只有在它们的后面加上一个?就可以实现非贪婪或最小匹配。
正则表达式的限定符有:
字符 描述
* 匹配前面的子表达式零次或多次。例如,zo* 能匹配 "z" 以及 "zoo"。* 等价于{0,}。
+ 匹配前面的子表达式一次或多次。例如,'zo+' 能匹配 "zo" 以及 "zoo",但不能匹配 "z"。+ 等价于 {1,}。
? 匹配前面的子表达式零次或一次。例如,"do(es)?" 可以匹配 "do" 或 "does" 中的"do" 。? 等价于 {0,1}。
{n} n 是一个非负整数。匹配确定的 n 次。例如,'o{2}' 不能匹配 "Bob" 中的 'o',但是能匹配 "food" 中的两个 o。
{n,} n 是一个非负整数。至少匹配n 次。例如,'o{2,}' 不能匹配 "Bob" 中的 'o',但能匹配 "foooood" 中的所有 o。'o{1,}' 等价于 'o+'。'o{0,}' 则等价于 'o*'。
{n,m} m 和 n 均为非负整数,其中n <= m。最少匹配 n 次且最多匹配 m 次。例如,"o{1,3}" 将匹配 "fooooood" 中的前三个 o。'o{0,1}' 等价于 'o?'。请注意在逗号和两个数之间不能有空格。

3.5 定位符

用来描述字符串或单词的边界,^和$分别指字符串的开始与结束,"b描述单词的前或后边界,"B表示非单词边界。不能对定位符使用限定符。

3.6 选择

用圆括号将所有选择项括起来,相邻的选择项之间用|分隔。但用圆括号会有一个副作用,是相关的匹配会被缓存,此时可用?:放在第一个选项前来消除这种副作用。
其中?:是非捕获元之一,还有两个非捕获元是?=和?!,这两个还有更多的含义,前者为正向预查,在任何开始匹配圆括号内的正则表达式模式的位置来匹配搜索字符串,后者为负向预查,在任何开始不匹配该正则表达式模式的位置来匹配搜索字符串。

3.7 后向引用

对一个正则表达式模式或部分模式两边添加圆括号将导致相关匹配存储到一个临时缓冲区中,所捕获的每个子匹配都按照在正则表达式模式中从左至右所遇到的内容存储。存储子匹配的缓冲区编号从 1 开始,连续编号直至最大 99 个子表达式。每个缓冲区都可以使用 '"n' 访问,其中 n 为一个标识特定缓冲区的一位或两位十进制数。
可以使用非捕获元字符 '?:', '?=', or '?!' 来忽略对相关匹配的保存。

4. 各种操作符的运算优先级

相同优先级的从左到右进行运算,不同优先级的运算先高后低。各种操作符的优先级从高到低如下:
操作符 描述
" 转义符
(), (?:), (?=), [] 圆括号和方括号
*, +, ?, {n}, {n,}, {n,m} 限定符
^, $, "anymetacharacter 位置和顺序
| “或”操作

5. 全部符号解释

字符 描述
" 将下一个字符标记为一个特殊字符、或一个原义字符、或一个 向后引用、或一个八进制转义符。例如,'n' 匹配字符 "n"。'"n' 匹配一个换行符。序列 '""' 匹配 """ 而 ""(" 则匹配 "("。
^ 匹配输入字符串的开始位置。如果设置了 RegExp 对象的 Multiline 属性,^ 也匹配 '"n' 或 '"r' 之后的位置。
$ 匹配输入字符串的结束位置。如果设置了RegExp 对象的 Multiline 属性,$ 也匹配 '"n' 或 '"r' 之前的位置。
* 匹配前面的子表达式零次或多次。例如,zo* 能匹配 "z" 以及 "zoo"。* 等价于{0,}。
+ 匹配前面的子表达式一次或多次。例如,'zo+' 能匹配 "zo" 以及 "zoo",但不能匹配 "z"。+ 等价于 {1,}。
? 匹配前面的子表达式零次或一次。例如,"do(es)?" 可以匹配 "do" 或 "does" 中的"do" 。? 等价于 {0,1}。
{n} n 是一个非负整数。匹配确定的 n 次。例如,'o{2}' 不能匹配 "Bob" 中的 'o',但是能匹配 "food" 中的两个 o。
{n,} n 是一个非负整数。至少匹配n 次。例如,'o{2,}' 不能匹配 "Bob" 中的 'o',但能匹配 "foooood" 中的所有 o。'o{1,}' 等价于 'o+'。'o{0,}' 则等价于 'o*'。
{n,m} m 和 n 均为非负整数,其中n <= m。最少匹配 n 次且最多匹配 m 次。例如,"o{1,3}" 将匹配 "fooooood" 中的前三个 o。'o{0,1}' 等价于 'o?'。请注意在逗号和两个数之间不能有空格。
? 当该字符紧跟在任何一个其他限制符 (*, +, ?, {n}, {n,}, {n,m}) 后面时,匹配模式是非贪婪的。非贪婪模式尽可能少的匹配所搜索的字符串,而默认的贪婪模式则尽可能多的匹配所搜索的字符串。例如,对于字符串 "oooo",'o+?' 将匹配单个 "o",而 'o+' 将匹配所有 'o'。
. 匹配除 ""n" 之外的任何单个字符。要匹配包括 '"n' 在内的任何字符,请使用象 '[."n]' 的模式。
(pattern) 匹配 pattern 并获取这一匹配。所获取的匹配可以从产生的 Matches 集合得到,在VBScript 中使用 SubMatches 集合,在JScript 中则使用 $0…$9 属性。要匹配圆括号字符,请使用 '"(' 或 '")'。
(?:pattern) 匹配 pattern 但不获取匹配结果,也就是说这是一个非获取匹配,不进行存储供以后使用。这在使用 "或" 字符 (|) 来组合一个模式的各个部分是很有用。例如, 'industr(?:y|ies) 就是一个比 'industry|industries' 更简略的表达式。
(?=pattern) 正向预查,在任何匹配 pattern 的字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不需要获取供以后使用。例如,'Windows (?=95|98|NT|2000)' 能匹配 "Windows 2000" 中的 "Windows" ,但不能匹配 "Windows 3.1" 中的 "Windows"。预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始。
(?!pattern) 负向预查,在任何不匹配 pattern 的字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不需要获取供以后使用。例如'Windows (?!95|98|NT|2000)' 能匹配 "Windows 3.1" 中的 "Windows",但不能匹配 "Windows 2000" 中的 "Windows"。预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始
x|y 匹配 x 或 y。例如,'z|food' 能匹配 "z" 或 "food"。'(z|f)ood' 则匹配 "zood" 或 "food"。
[xyz] 字符集合。匹配所包含的任意一个字符。例如, '[abc]' 可以匹配 "plain" 中的 'a'。
[^xyz] 负值字符集合。匹配未包含的任意字符。例如, '[^abc]' 可以匹配 "plain" 中的'p'。
[a-z] 字符范围。匹配指定范围内的任意字符。例如,'[a-z]' 可以匹配 'a' 到 'z' 范围内的任意小写字母字符。
[^a-z] 负值字符范围。匹配任何不在指定范围内的任意字符。例如,'[^a-z]' 可以匹配任何不在 'a' 到 'z' 范围内的任意字符。
"b 匹配一个单词边界,也就是指单词和空格间的位置。例如, 'er"b' 可以匹配"never" 中的 'er',但不能匹配 "verb" 中的 'er'。
"B 匹配非单词边界。'er"B' 能匹配 "verb" 中的 'er',但不能匹配 "never" 中的 'er'。
"cx 匹配由 x 指明的控制字符。例如, "cM 匹配一个 Control-M 或回车符。x 的值必须为 A-Z 或 a-z 之一。否则,将 c 视为一个原义的 'c' 字符。
"d 匹配一个数字字符。等价于 [0-9]。
"D 匹配一个非数字字符。等价于 [^0-9]。
"f 匹配一个换页符。等价于 "x0c 和 "cL。
"n 匹配一个换行符。等价于 "x0a 和 "cJ。
"r 匹配一个回车符。等价于 "x0d 和 "cM。
"s 匹配任何空白字符,包括空格、制表符、换页符等等。等价于 [ "f"n"r"t"v]。
"S 匹配任何非空白字符。等价于 [^ "f"n"r"t"v]。
"t 匹配一个制表符。等价于 "x09 和 "cI。
"v 匹配一个垂直制表符。等价于 "x0b 和 "cK。
"w 匹配包括下划线的任何单词字符。等价于'[A-Za-z0-9_]'。
"W 匹配任何非单词字符。等价于 '[^A-Za-z0-9_]'。
"xn 匹配 n,其中 n 为十六进制转义值。十六进制转义值必须为确定的两个数字长。例如,'"x41' 匹配 "A"。'"x041' 则等价于 '"x04' & "1"。正则表达式中可以使用 ASCII 编码。.
"num 匹配 num,其中 num 是一个正整数。对所获取的匹配的引用。例如,'(.)"1' 匹配两个连续的相同字符。
"n 标识一个八进制转义值或一个向后引用。如果 "n 之前至少 n 个获取的子表达式,则 n 为向后引用。否则,如果 n 为八进制数字 (0-7),则 n 为一个八进制转义值。
"nm 标识一个八进制转义值或一个向后引用。如果 "nm 之前至少有 nm 个获得子表达式,则 nm 为向后引用。如果 "nm 之前至少有 n 个获取,则 n 为一个后跟文字 m 的向后引用。如果前面的条件都不满足,若 n 和 m 均为八进制数字 (0-7),则 "nm 将匹配八进制转义值 nm。
"nml 如果 n 为八进制数字 (0-3),且 m 和 l 均为八进制数字 (0-7),则匹配八进制转义值 nml。
"un 匹配 n,其中 n 是一个用四个十六进制数字表示的 Unicode 字符。例如, "u00A9 匹配版权符号 (?)。

6. 部分例子

正则表达式 说明
/"b([a-z]+) "1"b/gi 一个单词连续出现的位置
/("w+):"/"/([^/:]+)(:"d*)?([^# ]*)/ 将一个URL解析为协议、域、端口及相对路径
/^(?:Chapter|Section) [1-9][0-9]{0,1}$/ 定位章节的位置
/[-a-z]/ A至z共26个字母再加一个-号。
/ter"b/ 可匹配chapter,而不能terminal
/"Bapt/ 可匹配chapter,而不能aptitude
/Windows(?=95 |98 |NT )/ 可匹配Windows95或Windows98或WindowsNT,当找到一个匹配后,从Windows后面开始进行下一次的检索匹配。

7. 正则表达式匹配规则

7.1 基本模式匹配

一切从最基本的开始。模式,是正规表达式最基本的元素,它们是一组描述字符串特征的字符。模式可以很简单,由普通的字符串组成,也可以非常复杂,往往用特殊的字符表示一个范围内的字符、重复出现,或表示上下文。例如:

^once

  这个模式包含一个特殊的字符^,表示该模式只匹配那些以once开头的字符串。例如该模式与字符串"once upon a time"匹配,与"There once was a man from NewYork"不匹配。正如如^符号表示开头一样,$符号用来匹配那些以给定模式结尾的字符串。

bucket$

  这个模式与"Who kept all of this cash in a bucket"匹配,与"buckets"不匹配。字符^和$同时使用时,表示精确匹配(字符串与模式一样)。例如:

^bucket$

  只匹配字符串"bucket"。如果一个模式不包括^和$,那么它与任何包含该模式的字符串匹配。例如:模式

once

与字符串

There once was a man from NewYork
Who kept all of his cash in a bucket.

是匹配的。

在该模式中的字母(o-n-c-e)是字面的字符,也就是说,他们表示该字母本身,数字也是一样的。其他一些稍微复杂的字符,如标点符号和白字符(空格、制表符等),要用到转义序列。所有的转义序列都用反斜杠(")打头。制表符的转义序列是:"t。所以如果我们要检测一个字符串是否以制表符开头,可以用这个模式:

^"t

类似的,用"n表示“新行”,"r表示回车。其他的特殊符号,可以用在前面加上反斜杠,如反斜杠本身用""表示,句号.用".表示,以此类推。

7.2 字符簇

在INTERNET的程序中,正规表达式通常用来验证用户的输入。当用户提交一个FORM以后,要判断输入的电话号码、地址、EMAIL地址、信用卡号码等是否有效,用普通的基于字面的字符是不够的。

所以要用一种更自由的描述我们要的模式的办法,它就是字符簇。要建立一个表示所有元音字符的字符簇,就把所有的元音字符放在一个方括号里:

[AaEeIiOoUu]

这个模式与任何元音字符匹配,但只能表示一个字符。用连字号可以表示一个字符的范围,如:

[a-z] //匹配所有的小写字母
[A-Z] //匹配所有的大写字母
[a-zA-Z] //匹配所有的字母
[0-9] //匹配所有的数字
[0-9"."-] //匹配所有的数字,句号和减号
[ "f"r"t"n] //匹配所有的白字符

同样的,这些也只表示一个字符,这是一个非常重要的。如果要匹配一个由一个小写字母和一位数字组成的字符串,比如"z2"、"t6"或"g7",但不是"ab2"、"r2d3" 或"b52"的话,用这个模式:

^[a-z][0-9]$

尽管[a-z]代表26个字母的范围,但在这里它只能与第一个字符是小写字母的字符串匹配。

前面曾经提到^表示字符串的开头,但它还有另外一个含义。当在一组方括号里使用^是,它表示“非”或“排除”的意思,常常用来剔除某个字符。还用前面的例子,我们要求第一个字符不能是数字:

^[^0-9][0-9]$

这个模式与"&5"、"g7"及"-2"是匹配的,但与"12"、"66"是不匹配的。下面是几个排除特定字符的例子:

[^a-z] //除了小写字母以外的所有字符
[^"""/"^] //除了(")(/)(^)之外的所有字符
[^"""'] //除了双引号(")和单引号(')之外的所有字符

特殊字符"." (点,句号)在正规表达式中用来表示除了“新行”之外的所有字符。所以模式"^.5$"与任何两个字符的、以数字5结尾和以其他非“新行”字符开头的字符串匹配。模式"."可以匹配任何字符串,除了空串和只包括一个“新行”的字符串。

PHP的正规表达式有一些内置的通用字符簇,列表如下:

字符簇 含义
[[:alpha:]] 任何字母
[[:digit:]] 任何数字
[[:alnum:]] 任何字母和数字
[[:space:]] 任何白字符
[[:upper:]] 任何大写字母
[[:lower:]] 任何小写字母
[[:punct:]] 任何标点符号
[[:xdigit:]] 任何16进制的数字,相当于[0-9a-fA-F]

7.3 确定重复出现

到现在为止,你已经知道如何去匹配一个字母或数字,但更多的情况下,可能要匹配一个单词或一组数字。一个单词有若干个字母组成,一组数字有若干个单数组成。跟在字符或字符簇后面的花括号({})用来确定前面的内容的重复出现的次数。

字符簇 含义
^[a-zA-Z_]$ 所有的字母和下划线
^[[:alpha:]]{3}$ 所有的3个字母的单词
^a$ 字母a
^a{4}$ aaaa
^a{2,4}$ aa,aaa或aaaa
^a{1,3}$ a,aa或aaa
^a{2,}$ 包含多于两个a的字符串
^a{2,} 如:aardvark和aaab,但apple不行
a{2,} 如:baad和aaa,但Nantucket不行
"t{2} 两个制表符
.{2} 所有的两个字符

这些例子描述了花括号的三种不同的用法。一个数字,{x}的意思是“前面的字符或字符簇只出现x次”;一个数字加逗号,{x,}的意思是“前面的内容出现x或更多的次数”;两个用逗号分隔的数字,{x,y}表示“前面的内容至少出现x次,但不超过y次”。我们可以把模式扩展到更多的单词或数字:

^[a-zA-Z0-9_]{1,}$ //所有包含一个以上的字母、数字或下划线的字符串
^[0-9]{1,}$ //所有的正数
^"-{0,1}[0-9]{1,}$ //所有的整数
^"-{0,1}[0-9]{0,}".{0,1}[0-9]{0,}$ //所有的小数

最后一个例子不太好理解,是吗?这么看吧:与所有以一个可选的负号("-{0,1})开头(^)、跟着0个或更多的数字([0-9]{0,})、和一个可选的小数点(".{0,1})再跟上0个或多个数字([0-9]{0,}),并且没有其他任何东西($)。下面你将知道能够使用的更为简单的方法。

特殊字符"?"与{0,1}是相等的,它们都代表着:“0个或1个前面的内容”或“前面的内容是可选的”。所以刚才的例子可以简化为:

^"-?[0-9]{0,}".?[0-9]{0,}$

特殊字符"*"与{0,}是相等的,它们都代表着“0个或多个前面的内容”。最后,字符"+"与 {1,}是相等的,表示“1个或多个前面的内容”,所以上面的4个例子可以写成:

^[a-zA-Z0-9_]+$ //所有包含一个以上的字母、数字或下划线的字符串
^[0-9]+$ //所有的正数
^"-?[0-9]+$ //所有的整数
^"-?[0-9]*".?[0-9]*$ //所有的小数

当然这并不能从技术上降低正规表达式的复杂性,但可以使它们更容易阅读。

参考文献:
JScript 和 VBScript 正则表达式

微软MSDN上的例子(英文):

Scanning for HREFS
Provides an example that searches an input string and prints out all the href="..." values and their locations in the string.
Changing Date Formats
Provides an example that replaces dates of the form mm/dd/yy with dates of the form dd-mm-yy.
Extracting URL Information
Provides an example that extracts a protocol and port number from a string containing a URL. For example, "http://www.contoso.com:8080/letters/readme.html" returns "http:8080".
Cleaning an Input String
provides an example that strips invalid non-alphanumeric characters from a string.
Confirming Valid E-Mail Format
Provides an example that you can use to verify that a string is in valid e-mail format

posted @ 2008-11-24 14:32 lqx 阅读(140) | 评论 (0)编辑 收藏

JavaScript中的正则表达式

正则表达式(regular expression)对象包含一个正则表达式模式(pattern)。它具有用正则表达式模式去匹配或代替一个串(string)中特定字符(或字符集合)的属性(properties)和方法(methods)。 要为一个单独的正则表达式添加属性,可以使用正则表达式构造函数(constructor function),无论何时被调用的预设置的正则表达式拥有静态的属性(the predefined RegExp object has static properties that are set whenever any regular expression is used, 我不知道我翻得对不对,将原文列出,请自行翻译)。
  • 创建:
    一个文本格式或正则表达式构造函数
    文本格式: /pattern/flags
    正则表达式构造函数: new RegExp("pattern"[,"flags"]);
  • 参数说明:
    pattern -- 一个正则表达式文本
    flags -- 如果存在,将是以下值:
    g: 全局匹配
    i: 忽略大小写
    gi: 以上组合

[注意] 文本格式的参数不用引号,而在用构造函数时的参数需要引号。如:/ab+c/i new RegExp("ab+c","i")是实现一样的功能。在构造函数中,一些特殊字符需要进行转意(在特殊字符前加""")。如:re = new RegExp("""w+")

正则表达式中的特殊字符

字符 含意
"

做为转意,即通常在"""后面的字符不按原来意义解释,如/b/匹配字符"b",当b前面加了反斜杆后/"b/,转意为匹配一个单词的边界。
-或-
对正则表达式功能字符的还原,如"*"匹配它前面元字符0次或多次,/a*/将匹配a,aa,aaa,加了"""后,/a"*/将只匹配"a*"。

^ 匹配一个输入或一行的开头,/^a/匹配"an A",而不匹配"An a"
$ 匹配一个输入或一行的结尾,/a$/匹配"An a",而不匹配"an A"
* 匹配前面元字符0次或多次,/ba*/将匹配b,ba,baa,baaa
+ 匹配前面元字符1次或多次,/ba*/将匹配ba,baa,baaa
? 匹配前面元字符0次或1次,/ba*/将匹配b,ba
(x) 匹配x保存x在名为$1...$9的变量中
x|y 匹配x或y
{n} 精确匹配n次
{n,} 匹配n次以上
{n,m} 匹配n-m次
[xyz] 字符集(character set),匹配这个集合中的任一一个字符(或元字符)
[^xyz] 不匹配这个集合中的任何一个字符
["b] 匹配一个退格符
"b 匹配一个单词的边界
"B 匹配一个单词的非边界
"cX 这儿,X是一个控制符,/"cM/匹配Ctrl-M
"d 匹配一个字数字符,/"d/ = /[0-9]/
"D 匹配一个非字数字符,/"D/ = /[^0-9]/
"n 匹配一个换行符
"r 匹配一个回车符
"s 匹配一个空白字符,包括"n,"r,"f,"t,"v等
"S 匹配一个非空白字符,等于/[^"n"f"r"t"v]/
"t 匹配一个制表符
"v 匹配一个重直制表符
"w 匹配一个可以组成单词的字符(alphanumeric,这是我的意译,含数字),包括下划线,如["w]匹配"$5.98"中的5,等于[a-zA-Z0-9]
"W 匹配一个不可以组成单词的字符,如["W]匹配"$5.98"中的$,等于[^a-zA-Z0-9]。

说了这么多了,我们来看一些正则表达式的实际应用的例子:

E-mail地址验证:
 function test_email(strEmail) {
  var myReg = /^[_a-z0-9]+@([_a-z0-9]+".)+[a-z0-9]{2,3}$/;
  if(myReg.test(strEmail)) return true;
  return false;
 }
HTML代码的屏蔽
 function mask_HTMLCode(strInput) {
   var myReg = /<("w+)>/;
   return strInput.replace(myReg, "&lt;$1&gt;");
 }


正则表达式对象的属性及方法
预定义的正则表达式拥有有以下静态属性:input, multiline, lastMatch, lastParen, leftContext, rightContext和$1到$9。其中input和multiline可以预设置。其他属性的值在执行过exec或test方法后被根据不同条件赋以不同的值。许多属性同时拥有长和短(perl风格)的两个名字,并且,这两个名字指向同一个值。(JavaScript模拟perl的正则表达式)
正则表达式对象的属性
属性 含义
$1...$9 如果它(们)存在,是匹配到的子串
$_ 参见input
$* 参见multiline
$& 参见lastMatch
$+ 参见lastParen
$` 参见leftContext
$'          参见rightContext
constructor    创建一个对象的一个特殊的函数原型
global       是否在整个串中匹配(bool型)
ignoreCase     匹配时是否忽略大小写(bool型)
input        被匹配的串
lastIndex     最后一次匹配的索引
lastParen     最后一个括号括起来的子串
leftContext    最近一次匹配以左的子串
multiline     是否进行多行匹配(bool型)
prototype     允许附加属性给对象
rightContext    最近一次匹配以右的子串
source       正则表达式模式
lastIndex     最后一次匹配的索引

正则表达式对象的方法
方法 含义
compile      正则表达式比较
exec        执行查找
test        进行匹配
toSource      返回特定对象的定义(literal representing),其值可用来创建一个新的对象。重载Object.toSource方法得到的。
toString      返回特定对象的串。重载Object.toString方法得到的。
valueOf      返回特定对象的原始值。重载Object.valueOf方法得到
例子
<script language = "JavaScript">
var myReg = /(w+)s(w+)/;
var str  = "John Smith";
var newstr = str.replace(myReg, "$2, $1");
document.write(newstr);
</script>
将输出"Smith, John"


〓简介〓
字符意义:对于字符,通常表示按字面意义,指出接着的字符为特殊字符,不作解释。
例如:/b/匹配字符'b',通过在b 前面加一个反斜杠,也就是/b/,则该字符变成特殊字符,表示匹配一个单词的分界线。或者:对于几个字符,通常说明是特殊的,指出紧接着的字符不是特殊的,而应该按字面解释。例如:*是一个特殊字符,匹配任意个字符(包括0个字符);例如:/a*/意味匹配0个或多个a。为了匹配字面上的*,在a前面加一个反斜杠;例如:/a*/匹配'a*'。

〓正文〓
字符
意义:对于字符,通常表示按字面意义,指出接着的字符为特殊字符,不作解释。
例如:/b/匹配字符'b',通过在b 前面加一个反斜杠,也就是/b/,则该字符变成特殊字符,表示
匹配一个单词的分界线。
或者:
对于几个字符,通常说明是特殊的,指出紧接着的字符不是特殊的,而应该按字面解释。
例如:*是一个特殊字符,匹配任意个字符(包括0个字符);例如:/a*/意味匹配0个或多个a。
为了匹配字面上的*,在a前面加一个反斜杠;例如:/a*/匹配'a*'。

字符^
意义:表示匹配的字符必须在最前边。
例如:/^A/不匹配"an A,"中的'A',但匹配"An A."中最前面的'A'。

字符$
意义:与^类似,匹配最末的字符。
例如:/t$/不匹配"eater"中的't',但匹配"eat"中的't'。

字符*
意义:匹配*前面的字符0次或n次。
例如:/bo*/匹配"A ghost booooed"中的'boooo'或"A bird warbled"中的'b',但不匹配"A goat g
runted"中的任何字符。

字符+
意义:匹配+号前面的字符1次或n次。等价于{1,}。
例如:/a+/匹配"candy"中的'a'和"caaaaaaandy."中的所有'a'。

字符?
意义:匹配?前面的字符0次或1次。
例如:/e?le?/匹配"angel"中的'el'和"angle."中的'le'。

字符.
意义:(小数点)匹配除换行符外的所有单个的字符。
例如:/.n/匹配"nay, an apple is on the tree"中的'an'和'on',但不匹配'nay'。


字符(x)
意义:匹配'x'并记录匹配的值。
例如:/(foo)/匹配和记录"foo bar."中的'foo'。匹配子串能被结果数组中的素[1], ..., [n] 返
回,或被RegExp对象的属性$1, ..., $9返回。

字符x|y
意义:匹配'x'或者'y'。
例如:/green|red/匹配"green apple"中的'green'和"red apple."中的'red'。

字符{n}
意义:这里的n是一个正整数。匹配前面的n个字符。
例如:/a{2}/不匹配"candy,"中的'a',但匹配"caandy," 中的所有'a'和"caaandy."中前面的两个
'a'。

字符{n,}
意义:这里的n是一个正整数。匹配至少n个前面的字符。
例如:/a{2,}不匹配"candy"中的'a',但匹配"caandy"中的所有'a'和"caaaaaaandy."中的所有'a'

字符{n,m}
意义:这里的n和m都是正整数。匹配至少n个最多m个前面的字符。
例如:/a{1,3}/不匹配"cndy"中的任何字符,但匹配 "candy,"中的'a',"caandy," 中的前面两个
'a'和"caaaaaaandy"中前面的三个'a',注意:即使"caaaaaaandy" 中有很多个'a',但只匹配前面的三
个'a'即"aaa"。

字符[xyz]
意义:一字符列表,匹配列出中的任一字符。你可以通过连字符-指出一个字符范围。
例如:[abcd]跟[a-c]一样。它们匹配"brisket"中的'b'和"ache"中的'c'。

字符[^xyz]
意义:一字符补集,也就是说,它匹配除了列出的字符外的所有东西。 你可以使用连字符-指出一
字符范围。
例如:[^abc]和[^a-c]等价,它们最早匹配"brisket"中的'r'和"chop."中的'h'。

字符[b]
意义:匹配一个空格(不要与b混淆)

字符b
意义:匹配一个单词的分界线,比如一个空格(不要与[b]混淆)
例如:/bnw/匹配"noonday"中的'no',/wyb/匹配"possibly yesterday."中的'ly'。

字符B
意义:匹配一个单词的非分界线
例如:/wBn/匹配"noonday"中的'on',/yBw/匹配"possibly yesterday."中的'ye'。

字符cX
意义:这里的X是一个控制字符。匹配一个字符串的控制字符。
例如:/cM/匹配一个字符串中的control-M。

字符d
意义:匹配一个数字,等价于[0-9]。
例如:/d/或/[0-9]/匹配"B2 is the suite number."中的'2'。

字符D
意义:匹配任何的非数字,等价于[^0-9]。
例如:/D/或/[^0-9]/匹配"B2 is the suite number."中的'B'。

字符f
意义:匹配一个表单符

字符n
意义:匹配一个换行符

字符r
意义:匹配一个回车符

字符s
意义:匹配一个单个white空格符,包括空格,tab,form feed,换行符,等价于[ fnrtv]。
例如:/sw*/匹配"foo bar."中的' bar'。

字符S
意义:匹配除white空格符以外的一个单个的字符,等价于[^ fnrtv]。
例如:/S/w*匹配"foo bar."中的'foo'。

字符t
意义:匹配一个制表符

字符v
意义:匹配一个顶头制表符

字符w
意义:匹配所有的数字和字母以及下划线,等价于[A-Za-z0-9_]。
例如:/w/匹配"apple,"中的'a',"$5.28,"中的'5'和"3D."中的'3'。

字符W
意义:匹配除数字、字母外及下划线外的其它字符,等价于[^A-Za-z0-9_]。
例如:/W/或者/[^$A-Za-z0-9_]/匹配"50%."中的'%'。

字符n
意义:这里的n是一个正整数。匹配一个正则表达式的最后一个子串的n的值(计数左圆括号)。

例如:/apple(,)sorange1/匹配"apple, orange, cherry, peach."中的'apple, orange',下面
有一个更加完整的例子。
注意:如果左圆括号中的数字比n指定的数字还小,则n取下一行的八进制escape作为描述。

字符ooctal和xhex
意义:这里的ooctal是一个八进制的escape值,而xhex是一个十六进制的escape值,允许在一个正则表达式中嵌入ASCII码。

posted @ 2008-11-24 14:31 lqx 阅读(215) | 评论 (0)编辑 收藏

java内存模型

内存模型 (memory model)
内存模型描述的是程序中各变量(实例域、静态域和数组元素)之间的关系,以及在实际计算机系统中将变量存储到内存和从内存取出变量这样的低层细节.

不同平台间的处理器架构将直接影响内存模型的结构.

在C或C++中, 可以利用不同操作平台下的内存模型来编写并发程序. 但是, 这带给开发人员的是, 更高的学习成本.
相比之下, java利用了自身虚拟机的优势, 使内存模型不束缚于具体的处理器架构, 真正实现了跨平台.
(针对hotspot jvm, jrockit等不同的jvm, 内存模型也会不相同)

内存模型的特征:
a, Visibility 可视性 (多核,多线程间数据的共享)
b, Ordering 有序性 (对内存进行的操作应该是有序的)



java 内存模型 ( java memory model )
根据Java Language Specification中的说明, jvm系统中存在一个主内存(Main Memory或Java Heap Memory),Java中所有变量都储存在主存中,对于所有线程都是共享的。

每条线程都有自己的工作内存(Working Memory),工作内存中保存的是主存中某些变量的拷贝,线程对所有变量的操作都是在工作内存中进行,线程之间无法相互直接访问,变量传递均需要通过主存完成。



其中, 工作内存里的变量, 在多核处理器下, 将大部分储存于处理器高速缓存中, 高速缓存在不经过内存时, 也是不可见的.

jmm怎么体现 可视性(Visibility) ?
在jmm中, 通过并发线程修改变量值, 必须将线程变量同步回主存后, 其他线程才能访问到.

jmm怎么体现 有序性(Ordering) ?

通过java提供的同步机制或volatile关键字, 来保证内存的访问顺序.



缓存一致性(cache coherency)

什么是缓存一致性?
它是一种管理多处理器系统的高速缓存区结构,其可以保证数据在高速缓存区到内存的传输中不会丢失或重复。(来自wikipedia)

举例理解:
假如有一个处理器有一个更新了的变量值位于其缓存中,但还没有被写入主内存,这样别的处理器就可能会看不到这个更新的值.

解决缓存一致性的方法?
a, 顺序一致性模型:
要求某处理器对所改变的变量值立即进行传播, 并确保该值被所有处理器接受后, 才能继续执行其他指令.

b, 释放一致性模型: (类似jmm cache coherency)
允许处理器将改变的变量值延迟到释放锁时才进行传播.



jmm缓存一致性模型 - "happens-before ordering(先行发生排序)"

一般情况下的示例程序:

x = 0;
y = 0;
i = 0;
j = 0;

// thread A
y = 1;
x = 1;

// thread B
i = x;
j = y;

在如上程序中, 如果线程A,B在无保障情况下运行, 那么i,j各会是什么值呢?

答案是, 不确定. (00,01,10,11都有可能出现)
这里没有使用java同步机制, 所以 jmm 有序性和可视性 都无法得到保障.

happens-before ordering( 先行发生排序) 如何避免这种情况?
排序原则已经做到:
a, 在程序顺序中, 线程中的每一个操作, 发生在当前操作后面将要出现的每一个操作之前.
b, 对象监视器的解锁发生在等待获取对象锁的线程之前.
c, 对volitile关键字修饰的变量写入操作, 发生在对该变量的读取之前.
d,
对一个线程的 Thread.start() 调用 发生在启动的线程中的所有操作之前.
e, 线程中的所有操作 发生在从这个线程的 Thread.join()成功返回的所有其他线程之前.

为了实现
happends-before ordering原则, java及jdk提供的工具:
a, synchronized关键字
b, volatile关键字
c, final变量
d, java.util.concurrent.locks包(since jdk 1.5)
e, java.util.concurrent.atmoic包(since jdk 1.5)
...

使用了happens-before ordering的例子:





(1) 获取对象监视器的锁(lock)

(2) 清空工作内存数据, 从主存复制变量到当前工作内存, 即同步数据 (read and load)

(3) 执行代码,改变共享变量值 (use and assign)

(4) 将工作内存数据刷回主存 (store and write)

(5) 释放对象监视器的锁 (unlock)

注意: 其中4,5两步是同时进行的.

这边最核心的就是第二步, 他同步了主内存,即前一个线程对变量改动的结果,可以被当前线程获知!(利用了happens-before ordering原则)

对比之前的例子
如果多个线程同时执行一段未经锁保护的代码段,很有可能某条线程已经改动了变量的值,但是其他线程却无法看到这个改动,依然在旧的变量值上进行运算,最终导致不可预料的运算结果。



经典j2ee设计模式Double-Checked Locking失效问题
双重检查锁定失效问题,一直是JMM无法避免的缺陷之一.了解DCL失效问题, 可以帮助我们深入JMM运行原理.

要展示DCL失效问题, 首先要理解一个重要概念- 延迟加载(lazy loading).

非单例的单线程延迟加载示例:
class Foo
{
private Resource res = null;
public Resource getResource()
{
    // 普通的延迟加载
if (res == null)
        res = new Resource();
return res;
}
}

非单例的 多线程延迟加载示例:
Class Foo
{
Private Resource res = null;
Public synchronized Resource getResource()
{
      // 获取实例操作使用同步方式, 性能不高
If (res == null) res = new Resource();
return res;
}
}

非单例的 DCL多线程延迟加载示例:
Class Foo
{
Private Resource res = null;
Public Resource getResource()
{
If (res == null)
{
       //只有在第一次初始化时,才使用同步方式.
synchronized(this)
{
if(res == null)
{
res = new Resource();
}
}
}
return res;
}
}

Double-Checked Locking看起来是非常完美的。但是很遗憾,根据Java的语言规范,上面的代码是不可靠的。

出现上述问题, 最重要的2个原因如下:
1, 编译器优化了程序指令, 以加快cpu处理速度.
2, 多核cpu动态调整指令顺序, 以加快并行运算能力.

问题出现的顺序:
1, 线程A, 发现对象未实例化, 准备开始实例化
2, 由于编译器优化了程序指令, 允许对象在构造函数未调用完前, 将
共享变量的引用指向 部分构造的对象, 虽然对象未完全实例化, 但已经不为null了.
3, 线程B, 发现部分构造的对象已不是null, 则直接返回了该对象.

不过, 一些著名的开源框架, 包括jive,lenya等也都在使用DCL模式, 且未见一些极端异常.
说明, DCL失效问题的出现率还是比较低的.
接下来就是性能与稳定之间的选择了?

DCL的替代
Initialize-On-Demand :

public class Foo {
    // 似有静态内部类, 只有当有引用时, 该类才会被装载
    private static class LazyFoo {
       public static Foo foo = new Foo();
    }

    public static Foo getInstance() {
       return LazyFoo.foo;
    }
}


维基百科的DCL解释:
http://en.wikipedia.org/wiki/Double-checked_locking

DCL的完美解决方案:
http://www.theserverside.com/patterns/thread.tss?thread_id=39606


总结:
多线程编程, 针对有写操作的变量, 必须 保证其所有引用点与主存中数据一致(考虑采用同步或volatile)
.

多核线程笔记-volatile原理与技巧

posted @ 2008-11-05 16:39 lqx 阅读(291) | 评论 (0)编辑 收藏

java 1.5 捕获线程异常

Executor 提供了管理终止的方法,以及可为跟踪一个或多个异步任务执行状况而生成 Future 的方法。

可以关闭 ExecutorService,这将导致其停止接受新任务。关闭后,执行程序将最后终止,这时没有任务在执行,也没有任务在等待执行,并且无法提交新任务。

通过创建并返回一个可用于取消执行和/或等待完成的 Future,方法 submit 扩展了基本方法 Executor.execute(java.lang.Runnable)。方法 invokeAnyinvokeAll 是批量执行的最常用形式,它们执行任务集合,然后等待至少一个,或全部任务完成(可使用 ExecutorCompletionService 类来编写这些方法的自定义变体)。

Executors 类提供了用于此包中所提供的执行程序服务的工厂方法。

用法示例

下面给出了一个网络服务的简单结构,这里线程池中的线程作为传入的请求。它使用了预先配置的 Executors.newFixedThreadPool(int) 工厂方法:
 class NetworkService {
private final ServerSocket serverSocket;
private final ExecutorService pool;

public NetworkService(int port, int poolSize) throws IOException {
serverSocket = new ServerSocket(port);
pool = Executors.newFixedThreadPool(poolSize);
}

public void serve() {
try {
for (;;) {
pool.execute(new Handler(serverSocket.accept()));
}
} catch (IOException ex) {
pool.shutdown();
}
}
}

class Handler implements Runnable {
private final Socket socket;
Handler(Socket socket) { this.socket = socket; }
public void run() {
// read and service request
}
}

posted @ 2008-11-05 15:46 lqx 阅读(480) | 评论 (0)编辑 收藏

js压缩

压缩不仅仅可以提高用户的下载速度,同时还可以加密代码,下面说下一个常用的js压缩方法:

首先使用dojo的工具shrinksafe(http://shrinksafe.dojotoolkit.org/)压缩一下,dojo的这个 工具会去掉注释,他的压缩不是简单的替换变量,而是利用了mozilla的一个工具,对js解析后才压缩,确保压缩后的代码不会出错。

dojo压缩后,并不会减少太多,下一步可以使用http://javascriptcompressor.com/这个站点进行更高层次的压缩,可惜只能登陆这个站点再压缩,只能将你的js代码复制的他的文本框,然后等他的压缩输出

经过这2步,你的js会变得既安全,文件又小

posted @ 2008-11-04 17:53 lqx 阅读(183) | 评论 (0)编辑 收藏

为何jsp 在resin下 乱码,但在tomcat下却工作良好?

关于JSP页面中的pageEncoding和contentType两种属性的区别:

pageEncoding是jsp文件本身的编码

contentType的charset是指服务器发送给客户端时的内容编码

JSP要经过两次的“编码”,第一阶段会用pageEncoding,第二阶段会用utf-8至utf-8,第三阶段就是由Tomcat出来的网页, 用的是contentType。Phontol.com

第一阶段是jsp编译成.java,它会根据pageEncoding的设定读取jsp,结果是由指定的编码方案翻译成统一的UTF-8 JAVA源码(即.java),如果pageEncoding设定错了,或没有设定,出来的就是中文乱码。Phontol.com

第二阶段是由JAVAC的JAVA源码至java byteCode的编译,不论JSP编写时候用的是什么编码方案,经过这个阶段的结果全部是UTF-8的encoding的java源码。Phontol.com

JAVAC用UTF-8的encoding读取java源码,编译成UTF-8 encoding的二进制码(即.class),这是JVM对常数字串在二进制码(java encoding)内表达的规范。Phontol.com

第三阶段是Tomcat(或其的application container)载入和执行阶段二的来的JAVA二进制码,输出的结果,也就是在客户端见到的,这时隐藏在阶段一和阶段二的参数contentType就发挥了功效

contentType的設定.

pageEncoding 和contentType的预设都是 ISO8859-1. 而随便设定了其中一个, 另一个就跟着一样了(TOMCAT4.1.27是如此). 但这不是绝对的, 这要看各自JSPC的处理方式. 而pageEncoding不等于contentType, 更有利亚洲区的文字 CJKV系JSP网页的开发和展示, (例pageEncoding=GB2312 不等于 contentType=utf-8)。


在Tomcat中如果在jsp中设定了pageEncoding,则contentType也跟着设定成相同的编码了,但是在resion中就不是,resin中还会用默认的,这点通过查看编译后的类servlet java文件就可以看到这一点,而问题恰恰就出在这里,所以,在jsp中,如果是在resin下最好还是明确的单独设定这2个属性。


jsp文件不像.java,.java在被编译器读入的时候默认采用的是操作系统所设定的locale所对应的编码,比如中国大陆就是GBK,台湾就是BIG5或者MS950。Phontol.com而一般我们不管是在记事本还是在ue中写代码,如果没有经过特别转码的话,写出来的都是本地编码格式的内容。Phontol.com所以编译器采用的方法刚好可以让虚拟机得到正确的资料。Phontol.com

但是jsp文件不是这样,它没有这个默认转码过程,但是指定了pageEncoding就可以实现正确转码了。Phontol.com

举个例子:

<%@ page contentType="text/html;charset=utf-8" %>

大都会打印出乱码,因为输入的“你好”是gbk的,但是服务器是否正确抓到“你好”不得而知。Phontol.com

但是如果更改为

<%@ page contentType="text/html;charset=utf-8" pageEncoding="GBK"%>

这样就服务器一定会是正确抓到“你好”了。Phontol.com


posted @ 2008-10-31 15:21 lqx 阅读(612) | 评论 (0)编辑 收藏

linux 下用 perl 发email

首先,在linux上安装perl-Mail-Sendmail-0.79-1.0.rh9.rf.noarch.rpm

perl 代码如下:

#
!/usr/bin/perl 
use Mail::Sendmail; 
$delay = 1;
$f_list="list.txt";
$line = 0;#skip the column title line
my $subject="xxx";
open(FILE,$f_list|| die "Can not open list file\n";
while(<FILE>){
chomp;
$line=$line+1;
next if($line==1);

(
$email,$passwd,$username,$yonghuming= split(/,/);


%mail = (
    from 
=> 'xxx@xxx.com',
    to 
=> $email,
    subject 
=> $subject,
    
'content-type' => 'text/html; charset="gbk"',
        );
$mail{body} = <<END_OF_BODY;
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gbk">
<title>个人邮箱登陆</title>
<style type="text/css">
<!--
body {
    margin
-left: 0px;
    margin
-top: 0px;
    margin
-right: 0px;
    margin
-bottom: 0px;
}
-->
</style>
<link href="images/css.css" rel="stylesheet" type="text/css">
<style type="text/css">
<!--
.style1 {font-size: 13px}
.style3 {color: #0066CC}
.style4 {color: #FF0000}
-->
</style>
</head>

<body>
<table width="60%" border="0" align="center" cellpadding="0" cellspacing="0">
  
<tr>
    
<td height="10" valign="bottom"><hr width="100%" size="10" color="#3399FF">test</td>
  
</tr> 
</table>
</body>
</html>

END_OF_BODY

sendmail(
%mail|| print "Error: $Mail::Sendmail::error\n";
sleep($delay); 
}
close(FILE);


list file 内容格式:
xx@163.com,xdf.com,xxx,xxx

posted @ 2008-10-17 09:33 lqx 阅读(377) | 评论 (0)编辑 收藏

firefox 3 call Components.classes

在firefox3下Components.classes 是不允许直接调用的,需要加上如下那句粗体的语句才可以
<script>
    netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
    var prefs = Components.classes['@mozilla.org/preferences-service;1'].getService(Components.interfaces.nsIPrefBranch);
        prefs.setBoolPref("dom.allow_scripts_to_close_windows", true);
</script>

posted @ 2008-09-18 13:16 lqx 阅读(1007) | 评论 (0)编辑 收藏

firefox extension 中 call click 事件


在chomal.manifest里如下设定,注意黄色部分,很关键
content     sample    chrome/content/  xpcnativewrappers=no
overlay chrome://browser/content/browser.xul chrome://sample/content/sample.xul

调用方式:
window.content.document.getElementById('sssddd').onclick();


参考如下连接

http://developer.mozilla.org/En/Safely_accessing_content_DOM_from_chrome

xpcnativewrappers

http://developer.mozilla.org/en/Chrome_Registration

posted @ 2008-09-17 13:44 lqx 阅读(293) | 评论 (0)编辑 收藏

div 底端对齐

<style type="text/css" media="all">
div,img
{margin: 0;padding: 0;border: 0;}


#content
{width: 303px;height: 404px;background: #F63;color: #000;font: 12px Arial,Helvetica,sans-serif;position: relative;}

#content div
{position: absolute;left: 0;bottom: 0;}
</style>
</head>
<body>
<div id="content">
<div>底端对齐 </div>
</div>

posted @ 2008-09-01 13:13 lqx 阅读(866) | 评论 (0)编辑 收藏

如何把表1的数据换成表2的形式







select  max(a.num) A,max(b.num) B,max(c.num) C,tttt.name from tttt
left join (select * from tttt where abc='C') c on c.abc=tttt.abc and c.name=tttt.name
left join (select * from tttt where abc='B') b on b.abc=tttt.abc and b.name=tttt.name
left join (select * from tttt where abc='A') a on a.abc=tttt.abc and a.name=tttt.name
group by name

posted @ 2008-07-16 11:18 lqx 阅读(109) | 评论 (0)编辑 收藏

【转】JAVA的内省(introspector)与反射(reflection)

 很多朋友在深入的接触 JAVA 语言后就会发现这样两个词:反射 (Reflection) 和内省 (Introspector) ,经常搞不清楚这到底是怎么回事,在什么场合下应用以及如何使用?今天把这二者放在一起介绍,因为它们二者是相辅相成的。

反射

相对而言,反射比内省更容易理解一点。用一句比较白的话来概括,反射就是让你可以通过名称来得到对象 ( 类,属性,方法 ) 的技术。例如我们可以通过类名来生成一个类的实例;知道了方法名,就可以调用这个方法;知道了属性名就可以访问这个属性的值。

还是写两个例子让大家更直观的了解反射的使用方法:
引用
//通过类名来构造一个类的实例
Class cls_str = Class.forName( "java.lang.String" );
// 上面这句很眼熟,因为使用过 JDBC 访问数据库的人都用过 J
Object str = cls_str.newInstance();
// 相当于 String str = new String();
//通过方法名来调用一个方法
String methodName = "length" ;
Method m = cls_str.getMethod(methodName, null );
System.out.println( "length is " + m.invoke(str, null ));
// 相当于 System.out.println(str.length());

上面的两个例子是比较常用方法。看到上面的例子就有人要发问了:为什么要这么麻烦呢?本来一条语句就完成的事情干吗要整这么复杂?没错,在上面的例子中确实没有必要这么麻烦。不过你想像这样一个应用程序,它支持动态的功能扩展,也就是说程序不重新启动但是可以自动加载新的功能,这个功能使用一个具体类来表示。首先我们必须为这些功能定义一个接口类,然后我们要求所有扩展的功能类必须实现我指定的接口,这个规定了应用程序和可扩展功能之间的接口规则,但是怎么动态加载呢?我们必须让应用程序知道要扩展的功能类的类名,比如是 test.Func1 ,当我们把这个类名 ( 字符串 ) 告诉应用程序后,它就可以使用我们第一个例子的方法来加载并启用新的功能。这就是类的反射,请问你有别的选择吗?

关于方法的反射建议大家看我的另外一篇文章《 利用 Turbine 的事件映射来扩展 Struts 的功能 》,地址是: http://www.javayou.com/article/CSDN/extend_struts.html 。这篇文章详细介绍了如果通过反射来扩展 Struts 框架的功能。

内省

内省是 Java 语言对 Bean 类属性、事件的一种缺省处理方法。例如类 A 中有属性 name, 那我们可以通过 getName,setName 来得到其值或者设置新的值。通过 getName/setName 来访问 name 属性,这就是默认的规则。 Java 中提供了一套 API 用来访问某个属性的 getter/setter 方法,通过这些 API 可以使你不需要了解这个规则(但你最好还是要搞清楚),这些 API 存放于包 java.beans 中。


一般的做法是通过类 Introspector 来获取某个对象的 BeanInfo 信息,然后通过 BeanInfo 来获取属性的描述器( PropertyDescriptor ),通过这个属性描述器就可以获取某个属性对应的 getter/setter 方法,然后我们就可以通过反射机制来调用这些方法。下面我们来看一个例子,这个例子把某个对象的所有属性名称和值都打印出来:


引用
/*
* Created on 2004-6-29
*/

package demo;


import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;


/**
* 内省演示例子
* @author liudong
*/

public class IntrospectorDemo {
String name;
public static void main(String[] args) throws Exception{
IntrospectorDemo demo = new IntrospectorDemo();
demo.setName( "Winter Lau" );

// 如果不想把父类的属性也列出来的话,
// 那 getBeanInfo 的第二个参数填写父类的信息
BeanInfo bi = Introspector.getBeanInfo(demo.getClass(), Object. class );
PropertyDescriptor[] props = bi.getPropertyDescriptors();
for ( int i=0;i<props.length;i++){
System.out.println(props[i].getName()+ "=" +
props[i].getReadMethod().invoke(demo, null ));
}

}

public String getName() {
return name;
}

public void setName(String name) {
this .name = name;
}
}


Web 开发框架 Struts 中的 FormBean 就是通过内省机制来将表单中的数据映射到类的属性上,因此要求 FormBean 的每个属性要有 getter/setter 方法。但也并不总是这样,什么意思呢?就是说对一个 Bean 类来讲,我可以没有属性,但是只要有 getter/setter 方法中的其中一个,那么 Java 的内省机制就会认为存在一个属性,比如类中有方法 setMobile ,那么就认为存在一个 mobile 的属性,这样可以方便我们把 Bean 类通过一个接口来定义而不用去关心具体实现,不用去关心 Bean 中数据的存储。比如我们可以把所有的 getter/setter 方法放到接口里定义,但是真正数据的存取则是在具体类中去实现,这样可提高系统的扩展性。

总结
将 Java 的反射以及内省应用到程序设计中去可以大大的提供程序的智能化和可扩展性。有很多项目都是采取这两种技术来实现其核心功能,例如我们前面提到的 Struts ,还有用于处理 XML 文件的 Digester 项目,其实应该说几乎所有的项目都或多或少的采用这两种技术。在实际应用过程中二者要相互结合方能发挥真正的智能化以及高度可扩展性。

另外,以下是SUN的java doc 对Introspector的解释:
public class Introspector
extends Object

The Introspector class provides a standard way for tools to learn about the properties, events, and methods supported by a target Java Bean.

For each of those three kinds of information, the Introspector will separately analyze the bean's class and superclasses looking for either explicit or implicit information and use that information to build a BeanInfo object that comprehensively describes the target bean.

For each class "Foo", explicit information may be available if there exists a corresponding "FooBeanInfo" class that provides a non-null value when queried for the information. We first look for the BeanInfo class by taking the full package-qualified name of the target bean class and appending "BeanInfo" to form a new class name. If this fails, then we take the final classname component of this name, and look for that class in each of the packages specified in the BeanInfo package search path.

Thus for a class such as "sun.xyz.OurButton" we would first look for a BeanInfo class called "sun.xyz.OurButtonBeanInfo" and if that failed we'd look in each package in the BeanInfo search path for an OurButtonBeanInfo class. With the default search path, this would mean looking for "sun.beans.infos.OurButtonBeanInfo".

If a class provides explicit BeanInfo about itself then we add that to the BeanInfo information we obtained from analyzing any derived classes, but we regard the explicit information as being definitive for the current class and its base classes, and do not proceed any further up the superclass chain.

If we don't find explicit BeanInfo on a class, we use low-level reflection to study the methods of the class and apply standard design patterns to identify property accessors, event sources, or public methods. We then proceed to analyze the class's superclass and add in the information from it (and possibly on up the superclass chain).

Because the Introspector caches BeanInfo classes for better performance, take care if you use it in an application that uses multiple class loaders. In general, when you destroy a ClassLoader that has been used to introspect classes, you should use the Introspector.flushCaches or Introspector.flushFromCaches method to flush all of the introspected classes out of the cache.

For more information about introspection and design patterns, please consult the JavaBeans specification.

posted @ 2008-07-14 17:21 lqx 阅读(366) | 评论 (0)编辑 收藏

[收藏]有关java I/O流的问题

FileInputStream 和 FileReader(头ho晕的)
FileReader 会做编码转换,FileInputStream会忠实于原始文件数据。任何形式的Reader都会涉及编码。

BufferedInputStream和BufferedOutputStream
BufferedInputStream: 添加了功能,即缓冲输入和支持 mark 和 reset 方法的能力。创建 BufferedInputStream 时即创建了一个内部缓冲区数组。读取或跳过流中的各字节时,必要时可根据所包含的输入流再次填充该内部缓冲区,一次填充多个字节。mark 操作记录输入流中的某个点,reset 操作导致在从所包含的输入流中获取新的字节前,再次读取自最后一次 mark 操作以来所读取的所有字节。
BufferedOutputStream:该类实现缓冲的输出流。通过设置这种输出流,应用程序就可以将各个字节写入基础输出流中,而不必为每次字节写入调用基础系统。

BufferedReader和FileReader
BufferedReader :由Reader类扩展而来,提供通用的缓冲方式文本读取,而且提供了很实用的readLine,读取分行文本很适合,BufferedReader是针对Reader的,不直接针对文件,也不是只针对文件读取。 
FileReader 是由java.io.InputStreamReade扩展来的,是针对文件读取的。实际使用时往往用   BufferedReader   bufferedreader   =   new   BufferedReader(new   FileReader("test.conf"));先建立一个文件reader,再用BufferedReader读。  
FileInputStream和Reader 
FileInputStream: 扩展自java.io.InputStream,InputStream提供的是字节流的读取,而非文本读取,这是和Reader类的根本区别。用 Reader读取出来的是char数组或者String   ,使用InputStream读取出来的是byte数组。  
Reader:Reader 类及其子类提供的字符流的读取char(16位),InputStream及其子类提供字节流的读取byte(8位),所以FileReader类是将文 件按字符流的方式读取,FileInputStream则按字节流的方式读取文件,BufferedReader的作用是提供缓冲, InputStreamReader可以将读如stream转换成字符流方式(即reader)是reader和stream之间的桥梁

BufferedInputStream和BufferedOutputStream的一个例子
import java.io.*;

public class BufferedStreamDemo...{
    public static void main(String[] args)...{
        try...{
            byte[] data=new byte[1];
           
            File srcFile=new File("BufferedStreamDemo.java");
            File desFile=new File("BufferedStreamDemo.txt");
           
            BufferedInputStream bufferedInputStream=new BufferedInputStream(new FileInputStream(srcFile));
            BufferedOutputStream bufferedOutputStream=new BufferedOutputStream(new FileOutputStream(desFile));
           
            System.out.println("复制文件: "+srcFile.length()+"字节");
           
            while(bufferedInputStream.read(data)!=-1)...{
                bufferedOutputStream.write(data);
            }
           
            //将缓冲区中的数据全部写出
            bufferedOutputStream.flush();
           
            System.out.println("复制完成");
           
            //显示输出BufferedStreamDemo.txt文件的内容
            bufferedInputStream =new BufferedInputStream(new FileInputStream(new File("BufferedStreamDemo.txt")));
            while(bufferedInputStream.read(data)!=-1)...{
                String str=new String(data);
                System.out.print(str);
            }
           
            bufferedInputStream.close();
            bufferedOutputStream.close();           
           
        }catch(ArrayIndexOutOfBoundsException e)...{
            System.out.println("using: java useFileStream src des");
            e.printStackTrace();
        }catch(IOException e)...{
            e.printStackTrace();
        }
    }
}

posted @ 2008-07-09 17:04 lqx 阅读(257) | 评论 (0)编辑 收藏

mysql 行变列的例句

select distinct item.reportoid, item.lineoid,  item.accountoid, sun.amount, mon.amount, tue.amount, wes.amount, thur.amount, fri.amount, sat.amount
from expenseitem item
left join (select reportoid, accountoid, lineoid, amount, itemDate from expenseitem
 where itemDate = '2007-11-04' ) sun
 on item.reportoid = sun.reportoid and
  item.accountoid = sun.accountoid and
  item.lineoid = sun.lineoid and
  item.itemDate = sun.itemDate
left join (select reportoid, accountoid,  lineoid, amount, itemDate from expenseitem
 where itemDate = adddate('2007-11-04', 1) ) mon
 on item.reportoid = mon.reportoid and
  item.accountoid = mon.accountoid and
  item.lineoid = mon.lineoid and
  item.itemDate = mon.itemDate
left join (select reportoid, accountoid,  lineoid,amount, itemDate from expenseitem
 where itemDate = adddate('2007-11-04', 2)) tue
 on item.reportoid = tue.reportoid and
  item.accountoid = tue.accountoid and
  item.lineoid = tue.lineoid and
  item.itemDate = tue.itemDate
left join (select reportoid, accountoid,  lineoid,amount, itemDate from expenseitem
 where itemDate = adddate('2007-11-04', 3)  ) wes
 on item.reportoid = wes.reportoid and
  item.accountoid = wes.accountoid and
  item.lineoid = wes.lineoid and
  item.itemDate = wes.itemDate
left join (select reportoid, accountoid,  lineoid,amount, itemDate from expenseitem
 where itemDate = adddate('2007-11-04', 4)  ) thur
 on item.reportoid = thur.reportoid and
  item.accountoid = thur.accountoid and
  item.lineoid = thur.lineoid and
  item.itemDate = thur.itemDate
left join (select reportoid, accountoid,  lineoid,amount, itemDate from expenseitem
 where itemDate = adddate('2007-11-04', 5)  ) fri
 on item.reportoid = fri.reportoid and
  item.accountoid = fri.accountoid and
  item.lineoid = fri.lineoid and
  item.itemDate = fri.itemDate
left join (select reportoid, accountoid,  lineoid,amount, itemDate from expenseitem
 where itemDate = adddate('2007-11-04', 6) ) sat
 on item.reportoid = sat.reportoid and
  item.accountoid = sat.accountoid and
  item.lineoid = sat.lineoid and
  item.itemDate = sat.itemDate
where item.reportoid = 3712
order by reportoid, accountoid;

posted @ 2008-07-08 10:52 lqx 阅读(645) | 评论 (0)编辑 收藏

sql server REVERSE ASCII

SELECT REVERSE('abc') AS Expr1


SELECT ascii('c') AS Expr1 取asc码

posted @ 2008-07-08 09:29 lqx 阅读(178) | 评论 (0)编辑 收藏

sql 在查询时,如果为空的时,如何用默认值代替空

COALESCE(a.end_,now())

posted @ 2008-07-04 17:31 lqx 阅读(748) | 评论 (0)编辑 收藏

如何用一条sql语句,返回某个月的所有天数

select DATE_ADD(date('2008-01-01'),INTERVAL days DAY) days from (select 0 days union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9 union select 10 union select 11 union select 12 union select 13 union select 14 union select 15 union select 16 union select 17 union select 18 union select 19 union select 20 union select 21 union select 22 union select 23 union select 24 union select 25 union select 26 union select 27 union select 28 union select 29 union select 30 union select 31) as b

posted @ 2008-07-04 17:29 lqx 阅读(648) | 评论 (0)编辑 收藏

wsdl 祥解

http://www.tutorialspoint.com/wsdl/index.htm

posted @ 2008-07-04 10:48 lqx 阅读(239) | 评论 (0)编辑 收藏

very cool tutorialspoint

http://www.tutorialspoint.com/

posted @ 2008-07-04 10:47 lqx 阅读(259) | 评论 (0)编辑 收藏

两段式提交

通过使用某种协议进行通信来完成分布式事务,被称为两段式提交。从名字上看,您可能已经知道有两个阶段:

 

  • 第一个阶段,即预提交
    • 事务协调器给每个事务管理器发送准备操作的信号。
    • 事务管理器将操作(通常是数据更新)步骤(或细节)写入事务日志。如果失败,事务管理器使用这些步骤重复操作。
    • 事务管理器本地创建事务并通知资源管理器对资源(例如,数据库或消息服务器)执行操作。
    • 资源管理器执行操作并向事务管理器报告成功(准备提交信号)或失败(准备回滚)。
    • 资源管理器等待事务管理器进一步的指令。
    • 事务管理器向事务协调器报告成功或失败。
  • 第二阶段,即提交阶段:在第二阶段中,第一阶段的结果将传送给所有事务管理器。如果任何事务管理器报告失败,所有的事务参与者都必须回滚。
    • 事务协调器让所有事务管理器提交(或回滚)。
    • 所有事务管理器将提交或回滚信息传递给其资源管理器。
    • 资源管理器将成功或失败提示返回给事务管理器。
    • 事务管理器向事务协调器报告成功或失败。

posted @ 2008-07-04 10:15 lqx 阅读(480) | 评论 (0)编辑 收藏