首页 \ 问答 \ 如何使用DataTables jQuery插件和正则表达式过滤短语?(How to phrase filter using DataTables jQuery plugin and regex?)

如何使用DataTables jQuery插件和正则表达式过滤短语?(How to phrase filter using DataTables jQuery plugin and regex?)

我正在使用jQuery DataTables插件对一组表结果进行过滤。 我的表列出了他们所属的客户和成员。 我有一个下拉列表,允许用户为特定组成员的客户过滤表格。 我的问题是客户可以是多个组的成员,所有这些都列在一个列中。

例如,Joe可能是以下组的成员:

  • 第1组
  • 第5组
  • 第10组

如果我定期过滤(见下文),并且用户从下拉列表中选择“组1”,它仍将显示属于“组10”的客户。

function fnFilterColumn ( i ){
    $('#results').dataTable().fnFilter(
        $("#filter").val(),
        i,
        false            
    );
}

如果我启用正则表达式(见下文),那么它会进行“精确”匹配。 因此,如果用户从下拉列表中选择“组1”,它将仅显示仅为“组1”成员的客户。

function fnFilterColumn ( i ){
     $('#results').dataTable().fnFilter(
         '^' + $("#filter").val() + '$',
         i,
         true        
    );
}

我将如何使其过滤“整个词组匹配”。 因此,“Group 1”的过滤器将显示“Group 1”中的过滤器,而不会抓取“Group 10”。 有任何想法吗?


I am using the jQuery DataTables plugin to do filtering on a set of table results. My table lists customers and members which they are a group of. I have a dropdown that allows the user to filter the table for those customers who members of a particular group. My problems is that customers can be members of multiple groups and all of these are listed in a single column.

For example, Joe might be a member of the following groups:

  • Group 1
  • Group 5
  • Group 10

If I do regular filtering (see below), and the user selects "Group 1" from the dropdown, it will still show customers who are members of "Group 10".

function fnFilterColumn ( i ){
    $('#results').dataTable().fnFilter(
        $("#filter").val(),
        i,
        false            
    );
}

If I enable Regex (see below), then it does an "exact" match. So if the user selects "Group 1" from the dropdown, it will only show customers who are only members of "Group 1".

function fnFilterColumn ( i ){
     $('#results').dataTable().fnFilter(
         '^' + $("#filter").val() + '$',
         i,
         true        
    );
}

How would I go about making it filter for "whole phrase matching". So a filter for "Group 1" will show those in "Group 1", without grabbing "Group 10" too. Any ideas?


原文:https://stackoverflow.com/questions/9995286
更新时间:2021-09-01 14:09

最满意答案

您的代码存在许多问题。

char* s1 = "Bob";

字符串文字创建一个只读的char数组; 这个数组是静态的,意味着它在程序的整个生命周期中都存在。 由于历史原因,它不是const ,因此如果您尝试修改它,编译器不一定会警告您,但您应该小心避免这样做。

s1指向该数组的第一个字符。 您不能修改*s1 。 为安全起见,您应该将指针声明为const

const char *s1 = "Bob";

如果你想要一个可修改的字符数组,你可以像这样创建它:

char s1[] = "Bob";

现在让我们看看剩下的代码:

if (*s1 >= 97 && *s1 <= 122)
     *s1 -= 32;
}

97122'a''z'的数字ASCII码。 32是小写字母和相应的大写字母之间的差异 - 再次,用ASCII表示。

C语言不保证字符以ASCII或与其兼容的任何字符集表示。 例如,在IBM大型机上,字符以EBCDIC表示,其中字母的代码不连续(有间隙),相应的小写字母和大写字母之间的差异为64,而不是32。

EBCDIC系统现在很少见,但即便如此,便携式代码往往比非可移植代码更清晰 ,即使代码是否适用于所有系统的任何实际问题也是如此。

我相信你知道,最好的方法是使用tolower函数:

*s1 = tolower((unsigned char)*s1);

注意转换为unsigned char 。 由于历史原因,在<ctype.h>中声明的to*()is*()函数表现得很奇怪。 它们不适用于char参数; 相反,它们处理在unsigned char范围内的int参数。 (他们也接受EOF ,通常为-1 )。 如果对plain char进行了签名,则传递恰好为负的char值会导致未定义的行为。 是的,这很烦人。

但是你说你不想使用tolower 。 (这很好;学会自己做这样的事情是一个很好的练习。)

如果你愿意假设大写字母是连续的,并且小写字母是连续的,那么你可以这样做:

if (*s1 >= 'a' && *s1 <= 'z') {
    *s1 -= 'a' - 'A';
}

这仍然不能移植到非ASCII系统,但如果您没有记住ASCII表,它会更容易阅读。

这也让你的逻辑向后变得更加明显。 你说你想转换成小写,但你的代码从小写转换为大写。

或者您可以使用将小写字母映射到大写字母的查找表:

char to_lower[CHAR_MAX] = { 0 }; /* sets all elements to 0 */
to_lower['A'] = 'a';
to_lower['B'] = 'b';
/* ... */
to_lower['Z'] = 'z';

或者,如果您的编译器支持复合文字:

const char to_lower[CHAR_MAX] = {
    ['A'] = 'a',
    ['B'] = 'b',
    /* ... */
};

我会留给你填写剩下的代码来使用它。

现在你可以看到为什么tolowertoupper函数存在 - 所以你不必处理所有这些东西(除了你需要的奇怪的unsigned char cast)。

更新:

回答您问题的新部分:

char* temp = malloc(100);   
temp = s1;

那个赋值temp = s1; 不复制分配的字符串; 它只是复制指针temp指向100个字节的已分配空间,但是您将temp指向(只读)字符串文字,并且您丢失了对分配空间的任何引用,从而产生内存泄漏。

您无法在C中分配字符串或数组。要复制字符串,请使用strcpy()函数:

char *temp = malloc(100);
if (temp == NULL) {     /* Don't assume the allocation was successful! */
    fprintf(stderr, "malloc failed\n");
    exit(EXIT_FAILURE);
}
strcpy(temp, s1);

另外,为什么我需要为已经在内存中的字符串分配内存?

它在内存中,但它是你不允许修改的内存。 如果要修改它,则需要将其复制到可修改的位置。 或者,正如我上面建议的那样,你可以把它放在读/写内存中:

char s[] = "Bob";

该初始化将字符串复制到数组s


There are a number of problems with your code.

char* s1 = "Bob";

A string literal creates a read-only array of char; this array is static meaning that it exists for the entire lifetime of your program. For historical reasons, it's not const, so the compiler won't necessarily warn you if you attempt to modify it, but you should carefully avoid doing so.

s1 points to the first character of that array. You may not modify *s1. For safety, you should declare the pointer as const:

const char *s1 = "Bob";

If you want a modifiable character array, you can create it like this:

char s1[] = "Bob";

Now let's look at the remaining code:

if (*s1 >= 97 && *s1 <= 122)
     *s1 -= 32;
}

97 and 122 are the numeric ASCII codes for 'a' and 'z'. 32 is the difference between a lower case letter and the corresponding upper case letter -- again, in ASCII.

The C language doesn't guarantee that characters are represented in ASCII, or in any of the character sets that are compatible with it. On an IBM mainframe, for example, characters are represented in EBCDIC, in which the codes for the letters are not contiguous (there are gaps), and the difference between corresponding lower case and upper case letters is 64, not 32.

EBCDIC systems are rare these days, but even so, portable code tends to be clearer than non-portable code, even aside from any practical issues of whether the code will work on all systems.

As I'm sure you know, the best way to do this is to use the tolower function:

*s1 = tolower((unsigned char)*s1);

Note the cast to unsigned char. The to*() and is*() functions declared in <ctype.h> are oddly behaved, for historical reasons. They don't work on char arguments; rather, they work on int arguments that are within the range of unsigned char. (They also accept EOF, which is typically -1). If plain char is signed, then passing a char value that happens to be negative causes undefined behavior. Yes, it's annoying.

But you say you don't want to use tolower. (Which is fine; learning to do things like this yourself is a good exercise.)

If you're willing to assume that upper case letters are contiguous, and that lower case letters are contiguous, then you can do something like this:

if (*s1 >= 'a' && *s1 <= 'z') {
    *s1 -= 'a' - 'A';
}

That's still not portable to non-ASCII systems, but it's a lot easier to read if you don't happen to have the ASCII table memorized.

It also makes it a little more obvious that you've got the logic backwards. You say you want to convert to lower case, but your code converts from lower case to upper case.

Or you can use a lookup table that maps lower case letters to upper case letters:

char to_lower[CHAR_MAX] = { 0 }; /* sets all elements to 0 */
to_lower['A'] = 'a';
to_lower['B'] = 'b';
/* ... */
to_lower['Z'] = 'z';

Or, if your compiler supports compound literals:

const char to_lower[CHAR_MAX] = {
    ['A'] = 'a',
    ['B'] = 'b',
    /* ... */
};

I'll leave it to you to fill in the rest write the code to use it.

And now you can see why the tolower and toupper functions exist -- so you don't have to deal with all this stuff (apart from the odd unsigned char casts you'll need).

UPDATE :

In response to the new parts of your question:

char* temp = malloc(100);   
temp = s1;

That assignment temp = s1; doesn't copy the allocated string; it just copies the pointer. temp points to 100 bytes of allocated space, but then you make temp point to the (read-only) string literal, and you've lost any references to the allocated space, creating a memory leak.

You can't assign strings or arrays in C. To copy a string, use the strcpy() function:

char *temp = malloc(100);
if (temp == NULL) {     /* Don't assume the allocation was successful! */
    fprintf(stderr, "malloc failed\n");
    exit(EXIT_FAILURE);
}
strcpy(temp, s1);

Also, why do I need to allocate memory for a string that already is in memory?

It's in memory, but it's memory that you're not allowed to modify. If you want to modify it, you need to copy it to a modifiable location. Or, as I suggested above, you can put it in read/write memory in the first place:

char s[] = "Bob";

That initialization copies the string into the array s.

相关问答

更多
  • JavaScript中有很多保留关键字,这些关键字是为“将来”使用而保留的。 他们不一定有当前的使用和描述。 MDN列出了其中一些在这里具有这种特殊的“未来使用”状态: https : //developer.mozilla.org/en/JavaScript/Reference/Reserved_Words (感谢DCoder ),您也可以阅读该文章: 以下内容被ECMAScript规范保留为将来的关键字。 目前它们没有特殊的功能,但它们可能在将来的某个时间,因此它们不能用作标识符。 这些关键字不能用于严 ...
  • 根据C ++标准(4.5 积分促销 ) 1如果int可以表示源的所有值,则整数转换等级(4.13)小于int的等级的除bool,char16_t,char32_t或wchar_t之外的整数类型的prvalue可以转换为int类型的prvalue类型; 否则,源prvalue可以转换为unsigned int类型的prvalue。 和(5个表达式) 10许多期望算术或枚举类型操作数的二元运算符会以类似的方式引起转换并产生结果类型。 目的是产生一个通用类型,它也是结果的类型。 这种模式称为通常的算术转换 ,其定 ...
  • 读取C声明符(这是*和[]的变量的一部分)是相当细微的。 有一些网站的提示: http://www.antlr.org/wiki/display/CS652/How+To+Read+C+Declarations http://www.ericgiguere.com/articles/reading-c-declarations.html char**是指向(可能多个)指针的指针(可能多个)char(s)。 例如,它可能是一个指向字符串指针的指针,或者是一个指向字符串指针数组的指针。 char*[]是指向ch ...
  • 从技术上讲,这是一种类型转换。 标准中用于描述语法的短语是“显式类型转换(功能符号)”。 来自标准([expr.type.conv] / 2)的效果描述如下: 如果初始化器是一个带括号的单个表达式,那么类型转换表达式与相应的强制转换表达式(8.4)是等价的(在定义中,如果定义的话)。 [...] [T]表达式是指定类型的一个前值,其结果对象用初始值设定项进行直接初始化(11.6)。 在这种情况下,你从'A'(一个字符字面)开始,它已经有了char 1类型,并且将它转换为char (所以这个转换没有效果并且什 ...
  • 您的代码存在许多问题。 char* s1 = "Bob"; 字符串文字创建一个只读的char数组; 这个数组是静态的,意味着它在程序的整个生命周期中都存在。 由于历史原因,它不是const ,因此如果您尝试修改它,编译器不一定会警告您,但您应该小心避免这样做。 s1指向该数组的第一个字符。 您不能修改*s1 。 为安全起见,您应该将指针声明为const : const char *s1 = "Bob"; 如果你想要一个可修改的字符数组,你可以像这样创建它: char s1[] = "Bob"; 现在让 ...
  • int low=strlen(array)-n; 是错的。 将数组大小作为不同的参数传递,如: int FindStringInSortedArray(char *key,char *array[],int n, int arraysize) 由于数组衰减成函数中的指针。 strlen宣言的形式 strlen (const char*) 并且你正在传递*array[]其类型衰减为char * * 。 在C99中,有三种基本情况,数组名称不会衰减为指向第一个元素的指针: 当它是& (address-of) ...
  • 你在步骤顺序中是正确的: CharFilter 标记生成器 TokenFilter 但是,CharFilter的主要目的是清理数据以使标记化更容易。 例如,通过剥离XML标记或用空格字符替换分隔符。 所以 - 我会将misc_simplifications作为misc_simplifications放在misc_simplifications过滤器之后应用。 { "settings" : { "index" : { "analysis" : { "analyz ...
  • 将"LINE TO BE SEPARATED"分配给char *line ,可以使line指向写入程序可执行文件的常量字符串。 你不能修改它。 你应该把这些变量声明为const char * 。 当声明为char[] ,你的字符串被声明在函数的堆栈中。 因此,您可以修改它。 When assigning "LINE TO BE SEPARATED" to char *line, you make line point to an constant string written in the program ...
  • strcat将其参数视为指向以空字符结尾的字符串的指针。 将一个char转换为char *是危险的,我可以想象没有理由它会有用(不要暗示你尝试它是愚蠢的 - 每个人在学习时都犯了愚蠢的错误。这就是为什么我们在这里。 ) 原因是它将解释单字节char ,加上围绕该char的额外sizeof(char*) - sizeof(char) (通常为3)字节作为指针,指向......任何地方。 您无法知道它指向的位置,因为其中3个字节超出了您的控制范围,因此无法知道它是否指向有效数据。 您可以将此作为第二种方法: s ...
  • 我知道这里的''a'就像是ascii,但距离是多少? 不是“类似”,它是 'a' ASCII码。 这里的距离意味着它与ASCII码的距离,即从“a”代码中减去代码。 为什么我们不将$ bl与'a'和'z'进行比较,看看它是否是小写的? 他们已经这样做了: 20 # check to see if in range ’a’-’z’ 21 cmpb $’a’, %bl 22 js nextchar 23 cmpb $’z’+1, %bl 24 jge nextchar I know $'a ...

相关文章

更多

最新问答

更多
  • 获取MVC 4使用的DisplayMode后缀(Get the DisplayMode Suffix being used by MVC 4)
  • 如何通过引用返回对象?(How is returning an object by reference possible?)
  • 矩阵如何存储在内存中?(How are matrices stored in memory?)
  • 每个请求的Java新会话?(Java New Session For Each Request?)
  • css:浮动div中重叠的标题h1(css: overlapping headlines h1 in floated divs)
  • 无论图像如何,Caffe预测同一类(Caffe predicts same class regardless of image)
  • xcode语法颜色编码解释?(xcode syntax color coding explained?)
  • 在Access 2010 Runtime中使用Office 2000校对工具(Use Office 2000 proofing tools in Access 2010 Runtime)
  • 从单独的Web主机将图像传输到服务器上(Getting images onto server from separate web host)
  • 从旧版本复制文件并保留它们(旧/新版本)(Copy a file from old revision and keep both of them (old / new revision))
  • 西安哪有PLC可控制编程的培训
  • 在Entity Framework中选择基类(Select base class in Entity Framework)
  • 在Android中出现错误“数据集和渲染器应该不为null,并且应该具有相同数量的系列”(Error “Dataset and renderer should be not null and should have the same number of series” in Android)
  • 电脑二级VF有什么用
  • Datamapper Ruby如何添加Hook方法(Datamapper Ruby How to add Hook Method)
  • 金华英语角.
  • 手机软件如何制作
  • 用于Android webview中图像保存的上下文菜单(Context Menu for Image Saving in an Android webview)
  • 注意:未定义的偏移量:PHP(Notice: Undefined offset: PHP)
  • 如何读R中的大数据集[复制](How to read large dataset in R [duplicate])
  • Unity 5 Heighmap与地形宽度/地形长度的分辨率关系?(Unity 5 Heighmap Resolution relationship to terrain width / terrain length?)
  • 如何通知PipedOutputStream线程写入最后一个字节的PipedInputStream线程?(How to notify PipedInputStream thread that PipedOutputStream thread has written last byte?)
  • python的访问器方法有哪些
  • DeviceNetworkInformation:哪个是哪个?(DeviceNetworkInformation: Which is which?)
  • 在Ruby中对组合进行排序(Sorting a combination in Ruby)
  • 网站开发的流程?
  • 使用Zend Framework 2中的JOIN sql检索数据(Retrieve data using JOIN sql in Zend Framework 2)
  • 条带格式类型格式模式编号无法正常工作(Stripes format type format pattern number not working properly)
  • 透明度错误IE11(Transparency bug IE11)
  • linux的基本操作命令。。。